0

I was wondering about the performance for new Yield keyword. Here is a sample code:

Module Module1

    Private test1 As TestClass
    Private test2 As TestClass

    Private processedValue1 As Integer = 0
    Private processedValue2 As Integer = 0

    Sub Main()

        test1 = New TestClass
        test2 = New TestClass
        AddHandler test2.OnData, AddressOf TestClass_OnData

        Dim s As New Stopwatch
        s.Start()
        For Each item In test1.GetAllEnum
            processedValue1 += 1
        Next
        s.Stop()

        Console.WriteLine("Iterator: " & s.ElapsedMilliseconds)

        s.Restart()
        test2.Start()
        s.Stop()

        Console.WriteLine("Event: " & s.ElapsedMilliseconds)
        Console.ReadLine()

    End Sub

    Private Sub TestClass_OnData(sender As TestClass, value As Integer)
        processedValue2 += 1
    End Sub

End Module

Public Class TestClass

    Public Iterator Function GetAllEnum() As IEnumerable(Of Integer)
        For i As Integer = 0 To 100000000
            Yield i
        Next
    End Function

    Public Sub Start()
        For i As Integer = 0 To 100000000
            RaiseEvent OnData(Me, i)
        Next
    End Sub

    Public Event OnData(sender As TestClass, value As Integer)

End Class

And the result is:

Iterator: 4271
Event: 1028

As we can see using Yield is about 4 times slower than traditional implementation.

Is there anyway to improve the performance?

Amir Pournasserian
  • 1,600
  • 5
  • 22
  • 46
  • 3
    You're not using a "traditional implementation" at all. Events and iterators are apples and oranges - I can't imagine having a situation where both design options are natural answers to the problem. Moreover, does your real code really care if 3 seconds are wasted when processing *100 million* values? In some cases optimization like this is important, but in most it's not. – Jon Skeet Nov 01 '13 at 17:11
  • I'm reading a big binary file (including more than 800 million objects). The performance is really is issue. But, when I'm using Event, I loose all the LINQ features (like GroupBy, OrderBy,...). I want to know if I can have both sides. – Amir Pournasserian Nov 01 '13 at 17:25
  • If you're reading a file, how long is spent in IO, or processing the objects? I very much doubt that the 3 seconds you're seeing here is really significant in the grand scheme of things. Also, was this captured in a debugger? If so, you may well find the overhead is much smaller. – Jon Skeet Nov 01 '13 at 17:50
  • Using SCSI's cache reading 2GB of data takes 900ms and converting bytes to objects takes 1200ms :) – Amir Pournasserian Nov 02 '13 at 03:51
  • 1
    Will your data actually be *in* the cache though? Note that on my ultrabook your code only takes ~960ms... are you sure you weren't running in the debugger? And what sort of conversion are you doing that's that quick? It really doesn't sound right to me... – Jon Skeet Nov 02 '13 at 08:25
  • @JonSkeet I'm testing on a dedicated server.When I see Performance Monitor's IO usage, it shows that there is no access to the file. So I think it uses the RAID controller's cache and I read all bytes of the file (using BinaryReader) with 16 threads in 910ms.Converting bytes to my my model (instance) takes about 1170ms. When I use IEnumerable to return yield the instance, it takes about 3800ms which is considerable. (I had a wrong count in my previous comment (800 million), the results are based on 80 million of objects.If you would like, I can update the post with complete source code.Thanks – Amir Pournasserian Nov 02 '13 at 15:56
  • It might be worth it. That really does sound like far more overhead than I'd expect - and as I said, your sample code takes less than a second on my laptop, which isn't exactly a powerhouse. – Jon Skeet Nov 02 '13 at 20:49
  • @JonSkeet Please visit this post: http://stackoverflow.com/questions/19786246/performance-comparison-of-ienumerable-and-raising-event-for-each-item-in-source Thanks – Amir Pournasserian Nov 05 '13 at 13:10
  • Why did you ask a new question rather than editing this one? – Jon Skeet Nov 05 '13 at 13:12

0 Answers0