Skip to content

Conversation

@liboz
Copy link
Collaborator

@liboz liboz commented Oct 13, 2016

As title.

On a few unrelated notes, I was doing some testing with your script and can't seem to measure any difference if any when CreateMap and CreateFilter create MapThenFilter/FilterThenMap . Are they even needed and/or are you able to measure the difference? Also does avoiding tail calls make a difference as well?

@manofstick
Copy link
Owner

manofstick commented Oct 13, 2016

Avoidtailcall made a difference on 32-bit; when I get home I'll check to see if it still does.

It probably would make a difference on 64-bit as well if you use a struct that is greater than 64-bits. For some "real world" types like that, try having a collection of some of the nodatime objects and see.

And I'm pretty sure I was still getting some benefit with the combined types, but I'll run some tests. I have definitely lightened the execution path, so might be able to get rid of them. I'll do some performance testing of those too tonight.

I'll merge this PR when I get home.

@manofstick
Copy link
Owner

@liboz

I still do see the benefit of MapThenFilter/FilterThenMap; mainly in the 32-bit runtime, but there appeared to be a slight improvement on 64-bit (after a number of runs, I was getting ~300ms ish with it and about ~310ms without.) In 32-bit the numbers were about ~665 vs ~730. Removing the avoidTailCall takes that time up to ~980.

Now in lets step things up a notch!

I added fold, so now sum can be implemented by changing the Seq.sum to |> Seq.fold (Checked.(+)) 0L

This takes the 32-bit one down to ~650 (minor) but brings the 64-bit one down to ~255! So for that particular case we're down to around 1/3 or the original time. A pretty good improvement I would say!

Comparing to Nesso's Stream library; like:

        data
        |> Nessos.Streams.Stream.ofSeq
        |> Nessos.Streams.Stream.map (fun n -> n * 5L)
        |> Nessos.Streams.Stream.filter (fun n -> n % 7L <> 0L)
        |> Nessos.Streams.Stream.map (fun n -> n / 11L)
        |> Nessos.Streams.Stream.sum

It comes in at ~210 for 62-bit, but ~1030 for 32-bit. So a bit faster, but not the (binary) orders of magnitude it was. (And it obviously has had the luxury of not having to retain compatibility with IEnumerable<>. so I think we're doing pretty well.)

...and, to whet your appetite, I have one last trick up my sleeve which I think might end up being quicker still!! But it does require an extra method being added to the Seq public interface, so I'm saving that for a separate PR once we complete the existing Seq surface.

@manofstick manofstick merged commit a066f34 into manofstick:manofstick-seq-composer Oct 13, 2016
@liboz
Copy link
Collaborator Author

liboz commented Oct 13, 2016

I'll try to confirm your findings tonight. Thanks for taking the time to check it again!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants