Performance Battle - LINQ Chunk vs MoreLINQ Batch!
August 28, 2024
• 452 views
You asked for it -- I delivered.
What's the big difference between MoreLINQ's Batch method and LINQ's Chunk method?
On the surface: Absolutely nothing.
But can we go... deeper? What will we find when we compare benchmarks for both of these things?
You might be surprised! Now I am not suggesting you use one or the other necessarily, but I'd like to show you the tools for you to be able to decide for yourself.
View Transcript
link chunk versus more link batch you all ask for it and I'm here to show you the comparisons hi my name is Nick centino and I'm a principal software engineering manager at Microsoft I started creating a video series demonstrating features from more link and I will continue to add to it but one of the first responses that I received was when we started looking at more link batch folks were asking hey look more link batch well what about Link's chunk method can we start to look at some of the performance differences between these two things and I figured this would be a great video to demonstrate the behavior and then we can look at the Benchmark so if that sounds interesting remember to subscribe to the channel and check out that pin comment for my courses on dome Trin that said let's jump over to
visual studio and compare both of these link methods okay on my screen right now I do have the more link batch method I'm just going to go put this back in the debug and I'm going to go run this and we'll see what batching looks like now this was covered in a previous video but what batching will do for us if we zoom in on here is when we have a batch of three across this set of numbers to 10 it will break it up into uh multiple batches so going to say three batches but it's four batches each of a size of three and of course this final batch is just one element because there's only 10 items chunking works the exact same so we don't need more link for it you can see Visual Studio has uh made it great out I can
even delete it this is built into to link now and I'm going to go ahead and run this and we should see that when we Chunk we get the same type of output right so one 1 2 3 so chunks of size three and there's four of them with the last one being a different size this is valuable for us to be able to split up collection sizes but now at this point we have two different ways that we can do it and in the original benchmarks that I showed I showed manual ways of going to do this but it's really better that we saw to be able to use built-in things or things like more link to do this for us what's going to be the difference between more links batch and the built-in Chunk from link now I should call that more link
as it's been developed over many years it has had methods that were added in so a lot of these extension methods that over time we have seen variations of these added into link itself chunking very much looks like batching right we just saw it's the exact same behavior so this seems to be one of the uh extension methods that was probably in more link and over time we had chunk added in to be available to us without any new get packages but now that we have people that are using more link and you're getting these things built into SHP for us to be able to use which one should you be using so let's go look at the Benchmark setup and then we'll look at the Benchmark results so I did mentioned in a previous video that I had benchmarks on this if you have
not seen that yet I'll link it right up top and you can go check that out but what we're going to be doing is basically not looking at the manual chunking approaches that I wrote so these are all commented out and instead we're going to compare more links matching to Links chunk method and if you notice these two benchmarks look very much the same in terms of how they're set up except one is going to use chunk this is from link and the other one here uses batch and this is from more link so that nugate package that we're talking about otherwise all that I'm doing is forcing a numeration across everything just to keep these the same right um when we deal with link so you can see the return type is an i enumerable this means that it will be lazy right doing
something like batch or using chunk which also returns an I inumerable when these are implemented at iterators that yield back data the sort of call to batch or the call to chunk is almost instant you're not doing any work until you evaluate so just to make sure everything was consistent I am going to essentially enumerate over every element just to keep it the same if we go up a little bit higher we can see that the parameters that I'm going to be using are collection size I just wanted to make sure that we could go across a spectrum of very small collections up to very large ones and then I am going to be batching uh the first sort of size of one means that we're not really batching um it's just going to be iterating over everything individually but given that we have these
two different apis that we can use we'll be able to see how they treat that when you basically have a very very small batch size versus up to something that's quite large before we continue on this is just a word from this video sponsor which is packed publishing packed has sent me yet another amazing book by Mark Price and if you don't know who Mark is he's created manyet books books they're available on Amazon and they're all taking over the Amazon bestseller section for net topics this book is called tools and skills for net 8 and it's available on Amazon like I mentioned it's filled with tons of information including things like AI prompting llms and different things like co-pilot that you can use in your development and it focuses on all of the tools and supporting things and not just language features like a
lot of other resources that are available so I do highly recommend this book for Mark Price just like all of his other books it's filed with tons of examples and it's sure to help guide you in working with C andet thanks and back to the video that's going to be the setup just a quick reminder that when you go to do this kind of stuff you do want to make sure that you are set up in release mode this is using filled with numbers here and we are going to be looking at basically more link matching compared to link chunk just a reminder that the first line in each little grouping here is going to be more links matching so between each pair more link is on the top standard link with chunking is on the bottom there are a couple of columns that I
want to call out so obviously these columns here I'm just going to circle them in red with a ter Mouse outline here but these are going to be the parameters that we're using this column with the rati I think is going to be extremely interesting because this is going to be where we're comparing performance relatively and same with the allocation ratio on the uh far right hand side the other interesting columns are this allocated one this is going to tell us the overall allocated memory that's being used and then of course the mean column is this uh performance column that we're interested in what's very helpful like I said is looking at the ratio column to be able to immediately tell us if there's strong differences between the two if the numbers are very close to both to one then they're going to be very
similar I did make links chunking method be the Baseline so links chunk will always be one and that will mean that more link batching having a smaller number in the ratio it will mean that it's faster and over here in the allocated column if the uh top number is smaller it will mean that there's fewer allocations uh conversely if the number is greater it will mean that it's either slower having more allocations than standard links chunk so with that said let's start diving into it in the first case where we have only a very small set of 10 elements and we have a batch size of one this is kind of a a crappy situation to be in when you're batching with one right and this is going to be a similar pattern we'll see throughout all of this but when we batch by one
we're effectively not using matching for a very good reason but I wanted to demonstrate what it looks like still you can see that more link uh is going to be uh significantly slower like 40% almost when we have that uh allocations are almost the same so not a huge difference here in terms of allocations but the performance is worse compared to standard links chunk if we start to go down a little bit lower and I can do these in a bit of a grouping here right if I highlight this ratio section what you'll notice is that more links matching is uh from about 75% of the time to down to half the time in terms of performance when we're dealing with a collect C size of 10 and a greater batch size so that's quite interesting because it is a small collection size still but
uh effectively it looks like there's probably some optimization that when the batch size is greater than the collection size that more link uh batch is doing something uh to kind of short circuit that functionality I haven't checked out the code but that would be my expectation when I see performance characteristics like this and interestingly if we look at the allocated column uh we do have significantly less memory allocated I mean we're only talking about not many bytes but less than half the number of bytes allocated for more links batching which is better so that's quite interesting next grouping is going to be the 1,000 element grouping and if we start to check out the ratio column so I'm going to highlight this part right here uh kind of interesting in the beginning when we're doing a batch size of one both of these have very
similar performance characteristics and the allocated part is the same so when you start to do just a size of one for batching around a th000 elements not really any different but we do start to see some very interesting behavior when again when the batch size is the same or greater than the collection size uh so these parts down here right you'll notice that more links batching is doing significantly better and this is sort of Illustrated here in the allocated column as well I think that what's happening is like I said there's some short circuit logic that says hey look the batching that we're doing it's the same size of the collection let's just kind of jump out of here pretty quick but kind of interesting I think it's worth calling out next section this is going to be what is that that is three that's
a million records so I'm going to highlight this group here as well this is where we're going to start to see that the tables turn a little bit so when we are getting into actual batching right this is actual batching Happening Here uh for the most part uh there is still an outlier when we are getting into splitting up the collection into chunks or batches it does look like the standard link chunk is going to do a better job in terms of performance so this one where we're splitting things up into the uh you know single element chunks uh in this case once we start getting up to a million elements we can see that more link is going to be uh underperforming by about 20% when we start to do the chunking so right here so this is where we're going to have chunk
sizes or batch sizes of a th it's about 25% slower with more link and then it's a little bit slower not by a whole lot but when we have uh 10 batches or 10 chunks of size 100,000 they're very comparable but it's a little bit slower for more link and then finally when the batch size is the same we always seem to be seeing more link really shine through so I just wanted to call that out sort of the pattern and one of the takeaways from this video was that when you batch size is the same more link seems to do better so I am curious if there's a really good optimization opportunity in Chunk in the standard library that we could have this uh optimized for us it's probably not a super common thing like why would you be chunking things and having them
the same size but I mean if you were writing code like that it would be nice if it was optimized so you don't have to worry about it if we jump over to the allocation column again we do see that the first two at least are very comp terrible let me highlight all four of them though for us first two are basically spot on in terms of allocations we do see that more link even though it was uh slower by a little bit right uh it did have fewer allocations so that's interesting maybe that's one of the considerations that if you were looking for a little bit fewer allocations and the performance is on par you might want to consider more link batching for that but again this short circuit logic or I'm assuming short circuit logic is is allocating fewer bytes which is pretty
cool and finally we're going to jump over to the last section which is going to be the 10 million collection size let's go highlight down here all of the ratios that we have single elements again uh slower with more link batching and then the other two where we have a collection or sorry a batch or chunk size of a th000 or 100,000 little bit slower uh with more link as well so uh roughly uh you know 4% or 9% slower in these cases and uh that's kind of what we started to see happening in the previous set and then as well when we uh because this final one is not going to be the full batch size that equals the collection right if we have a quick look I know these numbers are kind of hard to see written out here but the collection size
in this last grouping is 10 million and this batch size or chunk size is only 1 million so this is why you're not seeing more links batch pull ahead again here and that's because the collection size and the chunk size are not the same still so it does seem to be that when we are breaking things up into uh chunks using link Chunk we do get better performance characteristics especially with larger collection sizes if we jump over to the memory allocated in the far right column for this example it's either on par or a little bit better right like this is uh I would call this one basic Bally on par it's 99% of of it this one's 91% so you can see that it is starting to drop a little bit in terms of allocations relative to uh links chunk method but it does
seem like they are relatively comparable with allocations across the board more link seemingly uh allocating a little bit less than Link's chunk method but as we saw short circuiting logic seems to exist in more links batch and the link chunk method that's built in for us seems to do uh better for us in terms of performance when we have larger collection sizes with batch or chunk sizes that do not equal the entire collection size hopefully you found that interesting I'm not here to suggest that you must use one or the other I'm just trying to number one present some data to you to think about number two show you that you do have some options and number three remind you that you do have tools like benchmarking to be able to try these out so in this case because these apis are identical you could
try it out in your real code right you could go Benchmark your real code and swap these implementations out and see which one overall will perform better in your situation thanks so much for watching with the next video is available for more link examples you can check it out here thanks and I'll see you next time
Frequently Asked Questions
What is the main difference between LINQ's Chunk method and MoreLINQ's Batch method?
The main difference lies in their implementation and performance characteristics. While both methods serve to split collections into smaller groups, MoreLINQ's Batch has been optimized over time and may perform better in certain scenarios, especially when the batch size is equal to or greater than the collection size. However, for larger collections with varying batch sizes, LINQ's Chunk method tends to perform better.
How can I determine which method to use in my own projects?
I recommend benchmarking both methods in your specific context. Since the performance can vary based on the size of your collections and the batch sizes you choose, running your own benchmarks will give you the most accurate insight into which method performs better for your use case.
Are there any memory allocation differences between the two methods?
Yes, there are some differences in memory allocation. In many cases, MoreLINQ's Batch method allocates fewer bytes compared to LINQ's Chunk method, especially when the batch size is the same as the collection size. However, the performance characteristics can vary, so it's essential to consider both allocation and performance when making your choice.
These FAQs were generated by AI from the video transcript.