Using C# Yield for Readability and Performance
I must have read about "yield" a dozen times. Only recently have I began to understand what it does, and the real power that comes along with it. I’m going to show you some examples of where it can make your code more readable, and potentially more efficient.
To give you a very quick overview of how the yield functionality works, I first want to show you an example without it. The following code is simple, yet it’s a common pattern in the latest project I’m working on.
IList<string> FindBobs(IEnumerable<string> names)
{
var bobs = new List<string>();
foreach(var currName in names)
{
if(currName == "Bob")
bobs.Add(currName);
}
return bobs;
}
Notice that I take in an IEnumerable<string>, and return an IList<string>. My general rule of thumb has been to be as lenient as possible with my input, and as strict as possible with my output. For the input, it clearly makes sense to use IEnumerable if you’re just going to be looping through it with a foreach. For the output, I try to use an interface so that the implementation can be changed. However, I chose to return the list because the caller may be able to take advantage of the fact that I already went through the work of making it a list.
The problem is, my design isn’t chainable, and it’s creating lists all over the place. In reality, this probably doesn’t add up to much, but it’s there nonetheless.
Now, let’s take a look at the "yield" way of doing it, and then I’ll explain how and why it works:
IEnumerable<string> FindBobs(IEnumerable<string> names)
{
foreach(var currName in names)
{
if(currName == "Bob")
yield return currName;
}
}
In this version, we have changed the return type to IEnumerable<string>, and we’re using "yield return". Notice that I’m no longer creating a list. What’s happening is a little confusing, but I promise it’s actually incredibly simple once you understand it.
When you use the "yield return" keyphrase, .NET is wiring up a whole bunch of plumbing code for you, but for now you can pretend it’s magic. When you start to loop in the calling code (not listed here), this function actually gets called over and over again, but each time it resumes execution where it left off.
|
Typical Implementation |
Yield Implementation |
|
|
Although the execution of the yield implementation is a little more complicated, what we end up with is an implementation that "pulls" items one at a time instead of having to build an entire list before returning to the client.
In regards to the syntax, I personally think the yield syntax is simpler, and does a better job conveying what the method is actually doing. Even the fact that I’m returning IEnumerable tells the caller that its only concern should be that it can "foreach" over the return data. The caller can now make their own decision if they want to put it in a list, possibly at the expense of performance.
In the simple example I provided, you might not see much of an advantage. However, you’ll avoid unnecessary work when the caller can "short-circuit" or cancel looping through all of the items that the function will provide. When you start chaining methods using this technique together, this becomes more likely, and the amount of work saved can possibly multiply.
Ayende has a great example of using yield for a slick pipes & filters implementation. He even has a version that is multi-threaded which I find very intriguing.
One of my first reservations with using yield was that there is a potential performance implication. Since c# is keeping track of what is going on in what is essentially a state machine, there is a bit of overhead. Unfortunately, I can’t find any information that demonstrates the performance impact. I do think that the potential advantages I mentioned should outweigh the overhead concerns.
Conclusion
Yield can make your code more efficient and more readable. It’s been around since .NET 2.0, so there’s not much reason to avoid understanding and using it.
You can find detailed information about how the yield keyword works under the hood here.
Have you been using yield in interesting ways? Have you ever been bitten by using it? Leave a comment and let me know!

Garry Shutler said,
Wrote on February 4, 2009 @ 9:01 am
Have you included the “yield return break” for any reason? As far as I know it is superfluous in this case.
admin said,
Wrote on February 4, 2009 @ 9:22 am
Great catch Garry!
I updated the post and removed it. That statement was wrong either way, it should have been “yield break”.
Justin Etheredge said,
Wrote on February 4, 2009 @ 11:15 am
I think the performance implications are going to vary depending on what you are doing. If you are dealing with very large lists then you could very well improve performance because you don’t have to deal with a bunch of items being in memory at the same time.
Another important consideration is in lists where you don’t enumerate the entire thing. In which case using yield could be faster since you aren’t going to waste time spinning through the entire list.
And lastly, you also have to consider infinite series, which would not be possible at all using your original code. Perhaps I’ll write up a blog post discussing this topic. Hmmmmm.
Licantrop0 said,
Wrote on February 4, 2009 @ 11:19 am
A Linq2Entities solution could be clearer?
return names.Where(n => n == “Bob”);
you get rid also of the foreach cycle.
admin said,
Wrote on February 4, 2009 @ 11:32 am
@Justin
Yes, those reasons were part of the point I was trying to make. As far as the infinite series, people have mentioned that before, but it’s honestly not something I’ve actually seen a common need for. I wrote this post because I was only seeing the examples showing me how to get x digits of PI which isn’t terribly useful.
@Licantrop0
Yes, you could do that as well. In my actual code, I’m doing a little more advanced filtering. I simplified it to make the example easy to digest.
Tom said,
Wrote on February 4, 2009 @ 12:49 pm
Great information! Thanks!
One caveat is that you cannot use YieldingFunction().Count. that would clearly defeat the point of the yield, anyway.
Petar Repac said,
Wrote on February 4, 2009 @ 2:41 pm
yield return statement essentially makes the method a coroutine (http://en.wikipedia.org/wiki/Coroutine). It makes deferred query execution possible and is a basis for LINQ.
Judah Himango said,
Wrote on February 4, 2009 @ 8:56 pm
Yield return allocates a new class in the background, so it can be more expensive in terms of memory usage.
Like Justin said, it depends on how you’re using it.
Muhammad Mosa said,
Wrote on February 4, 2009 @ 8:56 pm
I found something interesting about yield too when working with Entity Framework.
For example if you have and Entity with called Category and You wished to make it implement interface called ICategory.
Using ObjectContext.CreateQuery.Cast() would through an exception.
I made a workaround this issue by using yield.
I made something the below wrapped in a method
foreach(var cateogry in context.CategorySet)
yield return category as ICategory
This is not going to be evaluated immediatly,
for example if you put this in a method called GetEnumerable() and called this method like this
var x = context.GetEnumerable();
this will not hit the database and evaulate your query.
What will hit the database is when you start iterating.
Thought to share it here on this cool post
sgwong said,
Wrote on February 5, 2009 @ 8:27 am
It looks like ruby yield statement. In ruby, yields is everywhere and straight forward, easy to use.
trendbender said,
Wrote on February 5, 2009 @ 11:37 am
very interesting, thx)
Timeless said,
Wrote on February 5, 2009 @ 2:15 pm
Excellent post, thanks. Like yourself, I read several times about the yield topic but never really graspt the idea and therefore never used it so far. I can surely see areas where yield can be quite useful, thanks again for the clear example and explanation.
micaleel said,
Wrote on February 8, 2009 @ 9:12 am
really nice. Thanks
Weekly Link Post 80 « Rhonda Tipton’s WebLog said,
Wrote on February 8, 2009 @ 9:47 pm
[...] Jason Young tells us about Using C# Yield for Readability and Performance. [...]
Interesting Finds: 2009.02.10 - gOODiDEA.NET said,
Wrote on February 9, 2009 @ 9:04 pm
[...] Using C# Yield for Readability and Performance [...]
Tuan Jinn said,
Wrote on April 27, 2009 @ 8:52 am
Awesome,
Interesting information and I have been usin’ yield for awhile now.
Thanks,
Tuan Jinn
Tuan Jinn said,
Wrote on April 27, 2009 @ 9:14 am
I encountered some problems (logical) while refactoring my code, which I am in doubt of using Yield.
I googled up and found this:
http://www.c-sharpcorner.com/UploadFile/dhiren.i.patel/Yield02092009234408PM/Yield.aspx
pretty disappointed about that post and clue less about whose is the original post.
Words are almost the same, except the method names are different.
Can you report or explain that? I’m quite allergic to this.
Tuan Jinn
admin said,
Wrote on April 27, 2009 @ 9:23 am
Tuan, I have contacted that site to have that removed. This post was copied without my permission.
Thank you for reporting that.
t4 said,
Wrote on May 14, 2009 @ 4:40 pm
I found the same article as Tuan (along with your own article, which looks to be the true source), and the article mentioned by Tuan still seems to be active. The author (patel.dhiren.i@gmail.com) doesn’t seem to have any reservations about copying your article for his own uses…
C# Yield Keyword « Vasu Balakrishnan’s Blog said,
Wrote on May 20, 2009 @ 2:36 pm
[...] Using C# Yield for Readability and Performance [...]
Jon Schneider said,
Wrote on June 22, 2009 @ 12:14 pm
This was helpful, thanks!
Matthew said,
Wrote on June 25, 2009 @ 11:06 pm
I haven’t checked memory usage, but yield appears to be awesome speed-wise, at least in this simple little test I ran.
Say I want to return a list of 20 items to process. The fastest way to allocate such a list should be a single allocation of a fixed size array, but it turns out that allocation, copying, and processing takes about 20% longer than creating an IEnumerable to directly iterate through the items. The advantage of the second case of course is there’s no need to copy the elements. You just allocate and access.
// elapsed: 00:00:03.4531250
static IEnumerable GetNumbers()
{
for(int i = 0; i < 20; i++)
{
yield return i;
}
}
// elapsed: 00:00:04.2500000
static IEnumerable GetNumbersArray()
{
int[] retval = new int[20];
for(int i = 0; i < 20; i++)
{
retval[i] = i;
}
return retval;
}
static void Main(string[] args)
{
int sum = 0;
DateTime begin = DateTime.Now;
for(int i = 0; i < (1 << 24); i++)
{
foreach(int j in
/*
GetNumbers()
*/
GetNumbersArray()
)
{
sum += j;
}
}
DateTime end = DateTime.Now;
Console.WriteLine(
“elapsed: ” +
(end – begin).ToString()
);
Console.WriteLine(sum);
}
Matthew said,
Wrote on June 25, 2009 @ 11:09 pm
I hate these web-based interfaces. That was supposed to be the typed version, IEnumerable<T>, not IEnumerable which is much slower.
Ed said,
Wrote on September 12, 2009 @ 10:19 pm
Why not just have a count property and a getItem(int index) method. Perfect clarity, less overhead and no surprises (also totality thread safe).
Understanding LINQ and LINQ to SQL (and EF) said,
Wrote on September 17, 2009 @ 10:18 am
[...] For a moment, forget that LINQ exists. Let’s say that you wanted to filter a list of names, to only get names that start with the letter “J”. You could write the following “utility” function: (if you don’t understand “yield return”, see this post on that topic). [...]
Nariman said,
Wrote on September 30, 2009 @ 9:12 am
There are definite performance gains to be had – here’s a good sample:
http://flimflan.com/blog/ThePowerOfYieldReturn.aspx
yield的使用及原理 « 宅爸爸的天空 said,
Wrote on January 16, 2010 @ 3:37 am
[...] [...]
dimpu said,
Wrote on April 7, 2010 @ 6:29 am
yes it is
Domain Events – Don’t observe us, we’ll observe you - db@net blog site said,
Wrote on April 13, 2010 @ 3:04 am
[...] Until now the dominating pattern regarding sequential input was the IEnumarable interface and the “yield” keyword in C#. Since the advent of LINQ and the deferred execution mechanism, this Design Pattern has received a [...]
C# yield keyword « Vincentpoon's Blog said,
Wrote on May 20, 2010 @ 10:55 pm
[...] http://www.ytechie.com/2009/02/using-c-yield-for-readability-and-performance.html [...]
User said,
Wrote on July 7, 2010 @ 1:49 pm
public IEnumerable Comment()
{
yield return “Good post!!”;
}