Uh oh!
There was an error while loading. Please reload this page.
Faster parallel array partition and choose - #1423
Conversation
msftclas
commented
Aug 12, 2016
Hi @jackmott, I'm your friendly neighborhood Microsoft Pull Request Bot (You can call me MSBOT). Thanks for your contribution! The agreement was validated by Microsoft and real humans are currently evaluating your PR. TTYL, MSBOT; |
Whats does this mean, from the QA tests. Something about assembly version being wrong, what would cause that? |
forki
commented
Aug 12, 2016
Probably unrelated |
jackmott
commented
Aug 12, 2016
Going to probably pull in the same trick for Parallel.choose in a minute. |
ReedCopsey
commented
Aug 12, 2016
Note that using Parallel.For can have bad repercussions in a situation where the algorithm is being used in a threaded context. If this is called on a thread while the other threads are already saturated via CPU usage, best case, it'd be the same as doing it in serial, and worst (and more likely) case, significantly slower. I'd be very careful about using Parallel loops within core library functions, since you can't control where they're going to be used, and this could be disastrous when used in highly threaded code. It's also unexpected - you'd expect to be safe using core library functions when threading at a "higher level" in your application, and this would make that assumption invalid. |
It was a Parallel.For originally, I just pulled the accumulation into it, rather than iterating over the array again to count it up afterwards. Also this is in a separate sub module - Array.Parallel, which was already in place, so chance of accidental improper usage is low. I agree with your points completely though, and was thinking of blogging about that very issue! |
cartermp
commented
Aug 12, 2016
@jackmott This is fantastic, as with your other PRs thus far. 👍 Could you also add your test script to this PR and further PRs? @smoothdeveloper and I were chatting, and he had mentioned that it would be great to have the perf test scripts for these changes in the repo so we can use them as a baseline for further improvements. The location for this would be in Thanks! |
jackmott
commented
Aug 12, 2016
@cartermp do you mean a script to test that performance has not regressed? Or for correctness? The former, I'm not sure how to do, since the old function wouldn't exist any more. The latter I assume already exists, since I haven't added a new function. Happy to help, need guidance. Thanks! |
KevinRansom
commented
Aug 12, 2016
Not a test case, more an indication of how the numbers were gathered. It gives other developers an idea about how to go about testing their performance improvements. Kevin From: Jack Mott [mailto:notifications@github.com] @cartermphttps://github.com/cartermp do you mean a script to test that performance has not regressed? Or for correctness? The former, I'm not sure how to do, since the old function wouldn't exist any more. The latter I assume already exists, since I haven't added a new function. Happy to help, need guidance. Thanks! — |
jackmott
commented
Aug 12, 2016
Gotcha. Would it be ok to pull BenchmarkDotNet into the solution? Are there other perf tests scripts I can use as a guide? |
ReedCopsey
commented
Aug 12, 2016
@jackmott Oh, great - sorry - just saw "for Array.choose" and wasn't thinking this was for Array.Parallel. Sorry about that! This is a great improvement - using the accumulators is definitely better. |
cartermp
commented
Aug 12, 2016
@jackmott I'd be fine with a package reference. I think it would be best if the Biggest thing is just to ensure that anyone can clone the repo and begin running the scripts to see performance results themselves. I'm also happy to iterate here and just get some scripts checked in while we figure out a good solution. |
jackmott
commented
Aug 12, 2016
Ok I will give it a go |
KevinRansom
commented
Aug 12, 2016
Given that the tests will run on different hardware, and that there is a before and after component. Seeing the results is less interesting than seeing the methodology. And the ability to examine the test code to look for where it may impzact the result demonstrated. Kevin From: Phillip Carter [mailto:notifications@github.com] @jackmotthttps://github.com/jackmott I'd be fine with a package reference. I think it would be best if the .dll for it wasn't checked in, though. As for examples, it looks like all we have is Compiler Perf Scriptshttps://github.com/Microsoft/visualfsharp/tree/master/tests/scripts. Not too much to go off of, so I think it's safe to say that you could do whatever you feel is reasonable and it'll be fine. Biggest thing is just to ensure that anyone can clone the repo and begin running the scripts to see performance results themselves. I'm also happy to iterate here and just get some scripts checked in while we figure out a good solution. — |
jackmott
commented
Aug 13, 2016
Sample perf test script added. Let me know if I should rename/relocate/revise. |
jackmott
commented
Aug 13, 2016
It would be neat if you had coverage of any perf relevant functions, and maybe weekly, check today's master against 1 week ago, report any that have regressed by some % for review. Massively time consuming test, couldn't do it on every PR/commit I don't think. |
KevinRansom
commented
Aug 13, 2016
@dotnet-bot test this please |
Appveyor Failure is due to appveyor timeout, it will be fixed by: #1425 |
KevinRansom
commented
Aug 13, 2016
@dotnet-bot test this please |
veikkoeeva
commented
Aug 14, 2016
@jackmott In that case dotnet/BenchmarkDotNet#155 looks like very promising. |
KevinRansom
commented
Aug 15, 2016
@jackmott If benchmark.net is a nuget package, then adding it will be great. |
jackmott
commented
Aug 15, 2016
@KevinRansom it is, but it pulls down a large set of dependencies I believe. Would you want it added to one of the existing projects? Create a new project with it inside the scripts folder? |
| [<Benchmark>] | ||
| member self.New () = | ||
| array |> partition (fun x -> x % 2 = 0) |
There was a problem hiding this comment.
I might be mistaken, but shouldn't this be partitionNew ?
KevinRansom
commented
Aug 15, 2016
Just add it to packages.config. It’s a one time cost and I’m guessing it’s less than the cost of pulling down the enormous set of dependencies we currently pull. I appreciate that optimizers may grumble … but the payback of a standardized way of reproducing and reporting performance issues is going to be tremendous. Your performance PR’s are already much easier to approve than others because of it. So I’m all for adding it. Kevin @KevinRansomhttps://github.com/KevinRansom it is, but it pulls down a large set of dependencies I believe. Would you want it added to one of the existing projects? Create a new project with it inside the scripts folder? — |
jackmott
commented
Aug 16, 2016
All set here, benchmarkdotnet added to packges.config |
KevinRansom
commented
Aug 20, 2016
Looks great, thanks for this work Kevin |
jackmott
commented
Aug 23, 2016
Anything else needed here? I think it is all ready. |
KevinRansom
commented
Aug 23, 2016
@jackmott Kevin |
Runtime is about 1.3x faster on my machine (4 core i7 mobile), with no memory use penalty. Would love input on this one, there may be some ways to improve on the approach. I am deep in uncharted Parallel.For territory.
BenchmarkDotNet results, partitioning a random int array with
(fun x -> x % 2 = 0)Note that the benchmark results are somewhat stochastic, they will bounce around from 35% to 10% better each time I run the suite, there doesn't appear to be a general trend where it gets better or worse moving from 1 million to 10 million. I've also used more complex predicates and the relative differences are similar.
Partition
Choose