Page 1 of 2 12 LastLast
Results 1 to 40 of 59

Thread: One Line or Two Lines?

  1. #1

    Thread Starter
    VB Addict Pradeep1210's Avatar
    Join Date
    Apr 2004
    Location
    Inside the CPU...
    Posts
    6,614

    One Line or Two Lines?

    Just like the popular view, I thought lesser code means better performance.

    I tested:
    vb.net Code:
    1. value = CType(object, ObjectType).Property
    against
    vb.net Code:
    1. Dim obj As ObjectType = CType(object, ObjectType)
    2. value = obj.Property
    The first method doesn't need an intermediate variable in between to store my object. This should also put less burden on the garbage collector as there is no variable. The 2nd way has an intermediate variable required in memory. So I thought it must be faster using the first way rather than the second way. But test results shows just the opposite here.

    vb.net Code:
    1. Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    2.     Dim sw As New Stopwatch, senderName As String
    3.  
    4.     For i As Integer = 1 To 5
    5.         sw.Reset() : sw.Start()
    6.         For j As Integer = 1 To 100000000
    7.             senderName = CType(sender, Button).Name
    8.         Next
    9.         sw.Stop()
    10.         Debug.Print("One Line : " & sw.ElapsedMilliseconds)
    11.  
    12.         sw.Reset() : sw.Start()
    13.         For j As Integer = 1 To 100000000
    14.             Dim btn As Button = CType(sender, Button)
    15.             senderName = btn.Name
    16.         Next
    17.         sw.Stop()
    18.         Debug.Print("Two Lines: " & sw.ElapsedMilliseconds)
    19.     Next
    20. End Sub

    This is the result:
    Code:
    One Line : 3786
    Two Lines: 3677
    One Line : 3787
    Two Lines: 3683
    One Line : 3787
    Two Lines: 3677
    One Line : 3790
    Two Lines: 3678
    One Line : 3783
    Two Lines: 3677
    Anyone know why this happens? Is the CLR doing some smart optimizations?

    Pradeep
    Pradeep, Microsoft MVP (Visual Basic)
    Please appreciate posts that have helped you by clicking icon on the left of the post.
    "A problem well stated is a problem half solved." — Charles F. Kettering

    Read articles on My Blog101 LINQ SamplesJSON ValidatorXML Schema Validator"How Do I" videos on MSDNVB.NET and C# ComparisonGood Coding PracticesVBForums Reputation SaverString EnumSuper Simple Tetris Game


    (2010-2013)
    NB: I do not answer coding questions via PM. If you want my help, then make a post and PM me it's link. If I can help, trust me I will...

  2. #2
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    40,106

    Re: One Line or Two Lines?

    Time to fire up ILDASM and look at the IL generated. For that reason alone, I prefer to put my two tests into two separate methods, so that you can bring up the IL for both functions in two different windows, align them side by side, and see exactly which lines are different.

    I suspect that if you do that you will find that in the second case, the btn variable is created once when the function is entered. Despite the fact that it is declared within the loop, and has no scope outside of the loop, I think that is handled by the compiler, and the declaration in IL will be once at the top of the method.

    You might find that in the first case, a button object is created each time through the loop. Not at all sure about this, though, which is why it is time for ILDASM.
    My usual boring signature: Nothing

  3. #3
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    40,106

    Re: One Line or Two Lines?

    Nevermind. I love this type of thing, so I modified your code and put it into my test project. Here are the two tests:

    Code:
        Private Sub test1(ByVal arg As Object)
            Dim rating As Integer = 7
            Dim n As Long = 0
            Dim x As Integer
    
            For x = 0 To 4000000
                n += CType(arg, TestCase1).No
            Next
    
    
        End Sub
    
        Private Sub test2(ByVal arg As Object)
            Dim rating As Integer = 3
            Dim n As Long = 0
            Dim x As Integer
            Dim setI As TestCase1
    
            For x = 0 To 4000000
                setI = CType(arg, TestCase1)
                n += setI.No
            Next
    
        End Sub
    Some of the declarations are just leftover junk. TestCase1 is just a little class I whipped up with a property that returns an integer. The class is created, then passed to each method in this order: Test1, Test2, Test2, Test1.

    My results confirmed yours. Test2 was faster each time. I then followed my own suggestion and looked at the two side by side in ILDASM. There were definitely differences, but all the key items were in each one. The total number of lines of IL for the loop in Test1 was LESS than the total number of lines of IL in Test2 by two lines (since the object was stored, then loaded, in Test2), yet Test1 was slower than Test2.

    Therefore, I see no reason why this should be true.
    My usual boring signature: Nothing

  4. #4
    Frenzied Member MaximilianMayrhofer's Avatar
    Join Date
    Aug 2007
    Location
    IM IN YR LOOP
    Posts
    2,001

    Re: One Line or Two Lines?

    A brilliant, and ultimately pointless conclusion. Perhaps if we step below ILDASM to the assembly code generated for each?

  5. #5
    I'm about to be a PowerPoster! mendhak's Avatar
    Join Date
    Feb 2002
    Location
    Ulaan Baator GooGoo: Frog
    Posts
    38,170

    Re: One Line or Two Lines?

    Rather than recreate a test by myself, can you show me the IL for the two cases?

  6. #6
    Frenzied Member MaximilianMayrhofer's Avatar
    Join Date
    Aug 2007
    Location
    IM IN YR LOOP
    Posts
    2,001

    Re: One Line or Two Lines?

    I still think that the most information will come from examination of the assembly code. For all we know, the second method while generating more ILDASM code actually results in a more efficient memory structure, reducing the time taken for data to be shuffled in and out of the register.

  7. #7
    Powered By Medtronic dbasnett's Avatar
    Join Date
    Dec 2007
    Location
    Jefferson City, MO
    Posts
    9,897

    Re: One Line or Two Lines?

    have i ever mentioned how much i hate line numbers!

    Code:
    Public Class Form1
        Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
            Dim sw As New Stopwatch, senderName As String
            Const loops As Integer = 100000000
            Debug.WriteLine(DateTime.Now.ToString)
            For i As Integer = 1 To 5
                sw.Reset() : sw.Start()
                For j As Integer = 1 To loops
                    senderName = DirectCast(sender, Button).Name
                Next
                sw.Stop()
                Debug.Print("One Line : " & sw.ElapsedMilliseconds)
    
    
                sw.Reset() : sw.Start()
                For j As Integer = 1 To loops
                    Dim btn As Button = DirectCast(sender, Button)
                    senderName = btn.Name
                Next
                sw.Stop()
                Debug.Print("Two Lines: " & sw.ElapsedMilliseconds)
            Next
        End Sub
        'we can see who has the faster processor
        '2/15/2009 11:15:49 AM
        'One Line : 6108
        'Two Lines: 6267
        'One Line : 6064
        'Two Lines: 6264
        'One Line : 6048
        'Two Lines: 6277
        'One Line : 6138
        'Two Lines: 6243
        'One Line : 6064
        'Two Lines: 6324
    End Class
    My First Computer -- Documentation Link (RT?M) -- Using the Debugger -- Prime Number Sieve
    Counting Bits -- Subnet Calculator -- UI Guidelines -- >> SerialPort Answer <<

    "Those who use Application.DoEvents have no idea what it does and those who know what it does never use it." John Wein

  8. #8
    Powered By Medtronic dbasnett's Avatar
    Join Date
    Dec 2007
    Location
    Jefferson City, MO
    Posts
    9,897

    Re: One Line or Two Lines?

    i think that with loops that long i would have to call the results even. a lot goes on in the PC in seconds.
    My First Computer -- Documentation Link (RT?M) -- Using the Debugger -- Prime Number Sieve
    Counting Bits -- Subnet Calculator -- UI Guidelines -- >> SerialPort Answer <<

    "Those who use Application.DoEvents have no idea what it does and those who know what it does never use it." John Wein

  9. #9
    Powered By Medtronic dbasnett's Avatar
    Join Date
    Dec 2007
    Location
    Jefferson City, MO
    Posts
    9,897

    Re: One Line or Two Lines?

    Code:
    Public Class Form1
        Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
            Dim sw As New Stopwatch, senderName As String
            Const loops As Integer = 1000
            Dim oneLine As Long
            Debug.WriteLine(DateTime.Now.ToString)
            For i As Integer = 1 To 5
                sw.Reset() : sw.Start()
                For j As Integer = 1 To loops
                    senderName = DirectCast(sender, Button).Name
                Next
                sw.Stop()
                oneLine = sw.ElapsedTicks
                Debug.WriteLine("One Line : " & sw.ElapsedTicks)
    
    
                sw.Reset() : sw.Start()
                For j As Integer = 1 To loops
                    Dim btn As Button = DirectCast(sender, Button)
                    senderName = btn.Name
                Next
                sw.Stop()
                Debug.Write("Two Lines: " & sw.ElapsedTicks & " ")
                Debug.WriteLine((sw.ElapsedTicks - oneLine).ToString)
            Next
        End Sub
        'we can see who has the faster processor
        '2/15/2009 11:28:38 AM
        'One Line : 312
        'Two Lines: 284 -28
        'One Line : 313
        'Two Lines: 285 -28
        'One Line : 313
        'Two Lines: 314 1
        'One Line : 278
        'Two Lines: 311 33
        'One Line : 278
        'Two Lines: 315 37
    End Class
    My First Computer -- Documentation Link (RT?M) -- Using the Debugger -- Prime Number Sieve
    Counting Bits -- Subnet Calculator -- UI Guidelines -- >> SerialPort Answer <<

    "Those who use Application.DoEvents have no idea what it does and those who know what it does never use it." John Wein

  10. #10
    I'm about to be a PowerPoster! mendhak's Avatar
    Join Date
    Feb 2002
    Location
    Ulaan Baator GooGoo: Frog
    Posts
    38,170

    Re: One Line or Two Lines?

    Never mind, I got the itch too. So I got this

    Two lines
    Code:
      IL_0060:  callvirt   instance void [System]System.Diagnostics.Stopwatch::Start()
      IL_0065:  nop
      IL_0066:  ldc.i4.1
      IL_0067:  stloc.s    V_5
      IL_0069:  ldarg.1
      IL_006a:  castclass  [System.Windows.Forms]System.Windows.Forms.Button
      IL_006f:  stloc.s    btn
      IL_0071:  ldloc.s    btn
      IL_0073:  callvirt   instance string [System.Windows.Forms]System.Windows.Forms.Control::get_Name()
      IL_0078:  stloc.0
      IL_0079:  nop
      IL_007a:  ldloc.s    V_5
      IL_007c:  ldc.i4.1
      IL_007d:  add.ovf
      IL_007e:  stloc.s    V_5
      IL_0080:  ldloc.s    V_5
      IL_0082:  ldc.i4     0x5f5e100
      IL_0087:  stloc.s    VB$CG$t_i4$S0
      IL_0089:  ldloc.s    VB$CG$t_i4$S0
      IL_008b:  ble.s      IL_0069
      IL_008d:  ldloc.1
      IL_008e:  callvirt   instance void [System]System.Diagnostics.Stopwatch::Stop()
    One line

    Code:
      IL_0060:  callvirt   instance void [System]System.Diagnostics.Stopwatch::Start()
      IL_0065:  nop
      IL_0066:  ldc.i4.1
      IL_0067:  stloc.s    V_5
      IL_0069:  ldarg.1
      IL_006a:  castclass  [System.Windows.Forms]System.Windows.Forms.Button
      IL_006f:  stloc.s    btn
      IL_0071:  ldloc.s    btn
      IL_0073:  callvirt   instance string [System.Windows.Forms]System.Windows.Forms.Control::get_Name()
      IL_0078:  stloc.0
      IL_0079:  nop
      IL_007a:  ldloc.s    V_5
      IL_007c:  ldc.i4.1
      IL_007d:  add.ovf
      IL_007e:  stloc.s    V_5
      IL_0080:  ldloc.s    V_5
      IL_0082:  ldc.i4     0x5f5e100
      IL_0087:  stloc.s    VB$CG$t_i4$S0
      IL_0089:  ldloc.s    VB$CG$t_i4$S0
      IL_008b:  ble.s      IL_0069
      IL_008d:  ldloc.1
      IL_008e:  callvirt   instance void [System]System.Diagnostics.Stopwatch::Stop()
    They have a difference of two lines between them where 'btn' is stored on the stack and loaded from the stack. It appears that the V_5 may be the key here. Because in the two line method you've declared a variable, it can be loaded onto a stack using stloc.0, stloc.1 and so on.

    But in the one line method, there's an implicit conversion and a need to hold it in a variable, which is why it declares a virtual label using stloc.s.

    The difference between stloc.x and stloc.s and ldloc.x and ldloc.s is not entirely clear to me but it appears that there is a bit of overhead involved in the pushing and popping of the stack as the variables are moved and cast in the *.s IL methods.

    Note that I simply copy pasted the code in #1, so I haven't bothered with optimization if any.
    Last edited by mendhak; Feb 15th, 2009 at 12:37 PM.

  11. #11
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    40,106

    Re: One Line or Two Lines?

    I disagree. Here is the output from the code I posted:

    Single line (Test1())
    .method private instance void test1(object arg) cil managed
    {
    // Code size 40 (0x28)
    .maxstack 2
    .locals init ([0] int64 n,
    [1] int32 rating,
    [2] int32 x,
    [3] int32 VB$CG$t_i4$S0)
    .language '{3A12D0B8-C26C-11D0-B442-00A0244A1DD2}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}'
    // Source File 'C:\Documents and Settings\charrington\My Documents\Visual Studio 2005\Projects\TestApp\TestApp\Form1.vb'
    //000066: Private Sub test1(ByVal arg As Object)
    IL_0000: nop
    //000067: Dim rating As Integer = 7
    IL_0001: ldc.i4.7
    IL_0002: stloc.1
    //000068: Dim n As Long = 0
    IL_0003: ldc.i4.0
    IL_0004: conv.i8
    IL_0005: stloc.0
    //000069: Dim x As Integer
    //000070:
    //000071: For x = 0 To 4000000
    IL_0006: ldc.i4.0
    IL_0007: stloc.2
    //000072: n += CType(arg, TestCase1).No
    IL_0008: ldloc.0
    IL_0009: ldarg.1
    IL_000a: castclass TestApp.TestCase1
    IL_000f: callvirt instance int32 TestApp.TestCase1::get_No()
    IL_0014: conv.i8
    IL_0015: add
    IL_0016: stloc.0
    //000073: Next
    IL_0017: nop
    IL_0018: ldloc.2
    IL_0019: ldc.i4.1
    IL_001a: add
    IL_001b: stloc.2
    IL_001c: ldloc.2
    IL_001d: ldc.i4 0x3d0900
    IL_0022: stloc.3
    IL_0023: ldloc.3
    IL_0024: ble.s IL_0008
    //000074:
    //000075:
    //000076: End Sub
    IL_0026: nop
    IL_0027: ret
    } // end of method Form1::test1
    Two lines (intermediate object) Test2
    .method private instance void test2(object arg) cil managed
    {
    // Code size 44 (0x2c)
    .maxstack 2
    .locals init ([0] int64 n,
    [1] int32 rating,
    [2] class TestApp.TestCase1 setI,
    [3] int32 x,
    [4] int32 VB$CG$t_i4$S0)
    .language '{3A12D0B8-C26C-11D0-B442-00A0244A1DD2}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}'
    // Source File 'C:\Documents and Settings\charrington\My Documents\Visual Studio 2005\Projects\TestApp\TestApp\Form1.vb'
    //000078: Private Sub test2(ByVal arg As Object)
    IL_0000: nop
    //000079: Dim rating As Integer = 3
    IL_0001: ldc.i4.3
    IL_0002: stloc.1
    //000080: Dim n As Long = 0
    IL_0003: ldc.i4.0
    IL_0004: conv.i8
    IL_0005: stloc.0
    //000081: Dim x As Integer
    //000082: Dim setI As TestCase1
    //000083:
    //000084: For x = 0 To 4000000
    IL_0006: ldc.i4.0
    IL_0007: stloc.3
    //000085: setI = CType(arg, TestCase1)
    IL_0008: ldarg.1
    IL_0009: castclass TestApp.TestCase1
    IL_000e: stloc.2
    //000086: n += setI.No
    IL_000f: ldloc.0
    IL_0010: ldloc.2
    IL_0011: callvirt instance int32 TestApp.TestCase1::get_No()
    IL_0016: conv.i8
    IL_0017: add
    IL_0018: stloc.0
    //000087: Next
    IL_0019: nop
    IL_001a: ldloc.3
    IL_001b: ldc.i4.1
    IL_001c: add
    IL_001d: stloc.3
    IL_001e: ldloc.3
    IL_001f: ldc.i4 0x3d0900
    IL_0024: stloc.s VB$CG$t_i4$S0
    IL_0026: ldloc.s VB$CG$t_i4$S0
    IL_0028: ble.s IL_0008
    //000088:
    //000089: End Sub
    IL_002a: nop
    IL_002b: ret
    } // end of method Form1::test2
    My code was stripped down to the bare bones for cleanliness, and compares integers instead of objects. I included the entire IL for each sub, just for completeness, but the difference is found between the For line and the Next line (naturally). I don't have any of that stlloc.s or stlloc.x stuff, yet I got the same results.
    My usual boring signature: Nothing

  12. #12
    I'm about to be a PowerPoster! mendhak's Avatar
    Join Date
    Feb 2002
    Location
    Ulaan Baator GooGoo: Frog
    Posts
    38,170

    Re: One Line or Two Lines?

    You disagree? You're not an ILDASM! Your ILDASM disagrees. You are merely a humble and lowly messenger.

    Oh but that aside, I think you should re-test or re-generate your IL after moving

    vb Code:
    1. Dim setI As TestCase1

    to inside the loop rather than having it sit outside and be reused.

  13. #13
    I'm about to be a PowerPoster! mendhak's Avatar
    Join Date
    Feb 2002
    Location
    Ulaan Baator GooGoo: Frog
    Posts
    38,170

    Re: One Line or Two Lines?

    Hmm, after modifying SH's code, I get this output

    One line: 595
    One line: 594
    One line: 590
    One line: 593
    One line: 590
    Two lines: 604
    Two lines: 601
    Two lines: 602
    Two lines: 608
    Two lines: 601

  14. #14

    Thread Starter
    VB Addict Pradeep1210's Avatar
    Join Date
    Apr 2004
    Location
    Inside the CPU...
    Posts
    6,614

    Re: One Line or Two Lines?

    What about my case? I couldn't get even one test that says One Line is faster than Two Lines.

    This is the lastest one:
    Code:
    One Line : 3790
    Two Lines: 3672
    One Line : 3793
    Two Lines: 3682
    One Line : 3787
    Two Lines: 3673
    One Line : 3782
    Two Lines: 3677
    One Line : 3784
    Two Lines: 3680
    Pradeep, Microsoft MVP (Visual Basic)
    Please appreciate posts that have helped you by clicking icon on the left of the post.
    "A problem well stated is a problem half solved." — Charles F. Kettering

    Read articles on My Blog101 LINQ SamplesJSON ValidatorXML Schema Validator"How Do I" videos on MSDNVB.NET and C# ComparisonGood Coding PracticesVBForums Reputation SaverString EnumSuper Simple Tetris Game


    (2010-2013)
    NB: I do not answer coding questions via PM. If you want my help, then make a post and PM me it's link. If I can help, trust me I will...

  15. #15
    I'm about to be a PowerPoster! mendhak's Avatar
    Join Date
    Feb 2002
    Location
    Ulaan Baator GooGoo: Frog
    Posts
    38,170

    Re: One Line or Two Lines?

    Hands up if you think this boils down to processors rather than code...

    I think we can know for sure if we all try the exact same code.

  16. #16
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    40,106

    Re: One Line or Two Lines?

    Quote Originally Posted by mendhak
    You disagree? You're not an ILDASM! Your ILDASM disagrees. You are merely a humble and lowly messenger.

    Oh but that aside, I think you should re-test or re-generate your IL after moving

    vb Code:
    1. Dim setI As TestCase1

    to inside the loop rather than having it sit outside and be reused.
    Lowly I may be, but humble I am not.

    I'm not on that computer anymore, and won't get back on it just to test that.

    How can this be a processor issue when all three of us got the same results? In all tests of one line vs two lines, two lines is always faster. The actual amounts vary due to the number of loops and processor speed, but the relative performance remains the same.

    EDIT: Oops, misread what the frog posted. Ok, so Pradeep and I get the same results, and Mendhak is the exception that proves the rule.

    Darn, maybe I WILL have to re-start that computer....but not for a few hours. Off to other things, for now.
    My usual boring signature: Nothing

  17. #17
    Powered By Medtronic dbasnett's Avatar
    Join Date
    Dec 2007
    Location
    Jefferson City, MO
    Posts
    9,897

    Re: One Line or Two Lines?

    Quote Originally Posted by Pradeep1210
    What about my case? I couldn't get even one test that says One Line is faster than Two Lines.

    This is the lastest one:
    Code:
    One Line : 3790
    Two Lines: 3672
    One Line : 3793
    Two Lines: 3682
    One Line : 3787
    Two Lines: 3673
    One Line : 3782
    Two Lines: 3677
    One Line : 3784
    Two Lines: 3680
    3 seconds on a PC is forever, so a .1 second difference is nothing really.

    switch the running order and see if you get different results.

    in your OP you said "Just like the popular view, I thought lesser code means better performance. " another adage is that 10% of the code accounts for 90% of the CPU usage.
    My First Computer -- Documentation Link (RT?M) -- Using the Debugger -- Prime Number Sieve
    Counting Bits -- Subnet Calculator -- UI Guidelines -- >> SerialPort Answer <<

    "Those who use Application.DoEvents have no idea what it does and those who know what it does never use it." John Wein

  18. #18
    Frenzied Member ntg's Avatar
    Join Date
    Sep 2004
    Posts
    1,449

    Re: One Line or Two Lines?

    I got itchy as well. My test code:
    VB Code:
    1. Module Module1
    2.  
    3.     Const LOOPS As Integer = 200000000
    4.  
    5.     Sub Main()
    6.  
    7.         TestWithoutCast()
    8.         TestWithExplicitCast()
    9.         TestWithoutCast()
    10.         TestWithExplicitCast()
    11.         Console.ReadLine()
    12.  
    13.     End Sub
    14.  
    15.     Private Sub TestWithExplicitCast()
    16.  
    17.         Dim sw As New Stopwatch
    18.         sw.Start()
    19.  
    20.         For i As Integer = 1 To LOOPS
    21.             Dim objTest As New test
    22.             Dim obj As Object = objTest
    23.  
    24.             Dim otherObj As test = CType(obj, test)
    25.             Dim val As Integer = otherObj.val
    26.         Next
    27.  
    28.         Console.WriteLine(sw.ElapsedMilliseconds.ToString + " <<< With explicit cast")
    29.     End Sub
    30.  
    31.     Private Sub TestWithoutCast()
    32.  
    33.         Dim sw As New Stopwatch
    34.         sw.Start()
    35.  
    36.         For i As Integer = 1 To LOOPS
    37.             Dim objTest As New test
    38.             Dim obj As Object = objTest
    39.  
    40.             Dim val As Integer = CType(obj, test).val
    41.         Next
    42.  
    43.         Console.WriteLine(sw.ElapsedMilliseconds.ToString + " <<< Without cast")
    44.  
    45.     End Sub
    46.  
    47.     Private Class test
    48.         Public val As Integer = 1
    49.     End Class
    50.  
    51. End Module
    The reason I'm calling the tests twice is to have any JIT time cancelled out during the second run and I'm glad I put it there. IL code for the test methods:
    Code:
    .method private static void  TestWithExplicitCast() cil managed
    {
      // Code size       82 (0x52)
      .maxstack  2
      .locals init ([0] class [System]System.Diagnostics.Stopwatch sw,
               [1] int32 i,
               [2] object obj,
               [3] class ConsoleApplication1.Module1/test objTest,
               [4] class ConsoleApplication1.Module1/test otherObj,
               [5] int32 val,
               [6] int64 VB$t_i8$S0)
      IL_0000:  newobj     instance void [System]System.Diagnostics.Stopwatch::.ctor()
      IL_0005:  stloc.0
      IL_0006:  ldloc.0
      IL_0007:  callvirt   instance void [System]System.Diagnostics.Stopwatch::Start()
      IL_000c:  ldc.i4.1
      IL_000d:  stloc.1
      IL_000e:  newobj     instance void ConsoleApplication1.Module1/test::.ctor()
      IL_0013:  stloc.3
      IL_0014:  ldloc.3
      IL_0015:  stloc.2
      IL_0016:  ldloc.2
      IL_0017:  castclass  ConsoleApplication1.Module1/test
      IL_001c:  stloc.s    otherObj
      IL_001e:  ldloc.s    otherObj
      IL_0020:  ldfld      int32 ConsoleApplication1.Module1/test::val
      IL_0025:  stloc.s    val
      IL_0027:  ldloc.1
      IL_0028:  ldc.i4.1
      IL_0029:  add.ovf
      IL_002a:  stloc.1
      IL_002b:  ldloc.1
      IL_002c:  ldc.i4     0xbebc200
      IL_0031:  ble.s      IL_000e
      IL_0033:  ldloc.0
      IL_0034:  callvirt   instance int64 [System]System.Diagnostics.Stopwatch::get_ElapsedMilliseconds()
      IL_0039:  stloc.s    VB$t_i8$S0
      IL_003b:  ldloca.s   VB$t_i8$S0
      IL_003d:  call       instance string [mscorlib]System.Int64::ToString()
      IL_0042:  ldstr      " <<< With explicit cast"
      IL_0047:  call       string [mscorlib]System.String::Concat(string,
                                                                  string)
      IL_004c:  call       void [mscorlib]System.Console::WriteLine(string)
      IL_0051:  ret
    } // end of method Module1::TestWithExplicitCast
    
    .method private static void  TestWithoutCast() cil managed
    {
      // Code size       78 (0x4e)
      .maxstack  2
      .locals init ([0] class [System]System.Diagnostics.Stopwatch sw,
               [1] int32 i,
               [2] object obj,
               [3] class ConsoleApplication1.Module1/test objTest,
               [4] int32 val,
               [5] int64 VB$t_i8$S0)
      IL_0000:  newobj     instance void [System]System.Diagnostics.Stopwatch::.ctor()
      IL_0005:  stloc.0
      IL_0006:  ldloc.0
      IL_0007:  callvirt   instance void [System]System.Diagnostics.Stopwatch::Start()
      IL_000c:  ldc.i4.1
      IL_000d:  stloc.1
      IL_000e:  newobj     instance void ConsoleApplication1.Module1/test::.ctor()
      IL_0013:  stloc.3
      IL_0014:  ldloc.3
      IL_0015:  stloc.2
      IL_0016:  ldloc.2
      IL_0017:  castclass  ConsoleApplication1.Module1/test
      IL_001c:  ldfld      int32 ConsoleApplication1.Module1/test::val
      IL_0021:  stloc.s    val
      IL_0023:  ldloc.1
      IL_0024:  ldc.i4.1
      IL_0025:  add.ovf
      IL_0026:  stloc.1
      IL_0027:  ldloc.1
      IL_0028:  ldc.i4     0xbebc200
      IL_002d:  ble.s      IL_000e
      IL_002f:  ldloc.0
      IL_0030:  callvirt   instance int64 [System]System.Diagnostics.Stopwatch::get_ElapsedMilliseconds()
      IL_0035:  stloc.s    VB$t_i8$S0
      IL_0037:  ldloca.s   VB$t_i8$S0
      IL_0039:  call       instance string [mscorlib]System.Int64::ToString()
      IL_003e:  ldstr      " <<< Without cast"
      IL_0043:  call       string [mscorlib]System.String::Concat(string,
                                                                  string)
      IL_0048:  call       void [mscorlib]System.Console::WriteLine(string)
      IL_004d:  ret
    } // end of method Module1::TestWithoutCast
    After looking at the IL, the declaration and use of otherObj (created and loaded from the stack) seems to be the only difference.

    Build in release mode with optimizations enabled. Results from within the IDE:
    3015 <<< Without cast
    3112 <<< With explicit cast
    3023 <<< Without cast
    3100 <<< With explicit cast

    Results from the command line:
    1254 <<< Without cast
    1199 <<< With explicit cast
    1129 <<< Without cast
    1199 <<< With explicit cast

    Note that when run from the command line the first test without cast is slower than the first test with the cast. This is because the code gets JITted behind the scenes and that time affects the test. In the second run of both tests, the results are what one would expect. BTW, I think that the declaration or not of an intermediate variable does not really help GC - it can routinely spot things like that otherwise there would be lots of crying .Net developers out there.

    Interestingly enough, when I disable optimizations I get the VB$CG$t_i4$S0 variable in my IL, just like mendhak and Shaggy.
    Last edited by ntg; Feb 15th, 2009 at 04:27 PM.
    "Feel the force...read the source..."
    Utilities: POPFileDebugViewProcess ExplorerWiresharkKeePassUltraVNCPic2Ascii
    .Net tools & open source: DotNetNukelog4NetCLRProfiler
    My open source projects: Thales SimulatorEFT CalculatorSystem Info ReporterVSS2SVNIBAN Functions
    Customer quote: "If the server has a RAID array, why should we bother with backups?"
    Programmer quote: "I never comment my code. Something that is hard to write should be impossible to comprehend."
    Ignorant quote: "I have no respect for universities, as they teach not practicle stuff, and charge money for"

  19. #19
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    40,106

    Re: One Line or Two Lines?

    OK, I moved the declaration inside the loop, so that my code for Test2 looks like this:
    Code:
    Private Sub test2(ByVal arg As Object)
            Dim rating As Integer = 3
            Dim n As Long = 0
            Dim x As Integer
    
            For x = 0 To 4000000
                Dim setI As TestCase1
                setI = CType(arg, TestCase1)
                n += setI.No
            Next
    
        End Sub
    I also moved the whole thing to a different computer. The timing is different on the two computers, of course, but the relative results are the same.

    The IL for the new version of Test2 is this:
    .method private instance void test2(object arg) cil managed
    {
    // Code size 37 (0x25)
    .maxstack 2
    .locals init ([0] int64 n,
    [1] int32 rating,
    [2] int32 x,
    [3] class TestApp.TestCase1 setI)
    IL_0000: ldc.i4.3
    IL_0001: stloc.1
    IL_0002: ldc.i4.0
    IL_0003: conv.i8
    IL_0004: stloc.0
    IL_0005: ldc.i4.0
    IL_0006: stloc.2
    IL_0007: ldarg.1
    IL_0008: castclass TestApp.TestCase1
    IL_000d: stloc.3
    IL_000e: ldloc.0
    IL_000f: ldloc.3
    IL_0010: callvirt instance int32 TestApp.TestCase1::get_No()
    IL_0015: conv.i8
    IL_0016: add
    IL_0017: stloc.0
    IL_0018: ldloc.2
    IL_0019: ldc.i4.1
    IL_001a: add
    IL_001b: stloc.2
    IL_001c: ldloc.2
    IL_001d: ldc.i4 0x3d0900
    IL_0022: ble.s IL_0007
    IL_0024: ret
    } // end of method Form1::test2
    This IL version is the release version, rather than the, easier to follow, debug version, but the result is still the same. When compared to the release version of Test1 (the code is the same as in my original post):
    .method private instance void test1(object arg) cil managed
    {
    // Code size 35 (0x23)
    .maxstack 2
    .locals init ([0] int64 n,
    [1] int32 rating,
    [2] int32 x)
    IL_0000: ldc.i4.7
    IL_0001: stloc.1
    IL_0002: ldc.i4.0
    IL_0003: conv.i8
    IL_0004: stloc.0
    IL_0005: ldc.i4.0
    IL_0006: stloc.2
    IL_0007: ldloc.0
    IL_0008: ldarg.1
    IL_0009: castclass TestApp.TestCase1
    IL_000e: callvirt instance int32 TestApp.TestCase1::get_No()
    IL_0013: conv.i8
    IL_0014: add
    IL_0015: stloc.0
    IL_0016: ldloc.2
    IL_0017: ldc.i4.1
    IL_0018: add
    IL_0019: stloc.2
    IL_001a: ldloc.2
    IL_001b: ldc.i4 0x3d0900
    IL_0020: ble.s IL_0007
    IL_0022: ret
    } // end of method Form1::test1
    Test2 performs considerably better than Test1 in release version (~10%), and marginally better than Test1 in debug version (~2%). I didn't test the release version of the code on the first computer.

    Therefore, I don't see how computer differences can account for this. There are two extra lines of IL (a store and load) in Test2 than in Test1, yet Test2 runs faster. The only way I can account for Mendhaks anomalous results are by attacking his character, which, while satisfying and politically correct, really doesn't help anything.
    My usual boring signature: Nothing

  20. #20

    Thread Starter
    VB Addict Pradeep1210's Avatar
    Join Date
    Apr 2004
    Location
    Inside the CPU...
    Posts
    6,614

    Re: One Line or Two Lines?

    Quote Originally Posted by dbasnett
    3 seconds on a PC is forever, so a .1 second difference is nothing really.

    switch the running order and see if you get different results.

    in your OP you said "Just like the popular view, I thought lesser code means better performance. " another adage is that 10% of the code accounts for 90% of the CPU usage.
    Maybe it is a very small difference, but worth knowing why there is such a difference. It can't be due to external factors like OS doing some other background tasks during that time, since it seems to affect only one of them and not the other.
    I was just interested in knowing how the two lines are always faster than the single line code, though logically single line code should have performed better as the compiler has lesser overheads involved.
    How does the compiler favor 2 lines instead of the one line code even after having overheads of more instructions and memory?

    Switching the order of test doesn't seem to affect the test result. 2 lines are still faster than the single line code.
    Pradeep, Microsoft MVP (Visual Basic)
    Please appreciate posts that have helped you by clicking icon on the left of the post.
    "A problem well stated is a problem half solved." — Charles F. Kettering

    Read articles on My Blog101 LINQ SamplesJSON ValidatorXML Schema Validator"How Do I" videos on MSDNVB.NET and C# ComparisonGood Coding PracticesVBForums Reputation SaverString EnumSuper Simple Tetris Game


    (2010-2013)
    NB: I do not answer coding questions via PM. If you want my help, then make a post and PM me it's link. If I can help, trust me I will...

  21. #21
    PowerPoster SJWhiteley's Avatar
    Join Date
    Feb 2009
    Location
    South of the Mason-Dixon Line
    Posts
    2,256

    Re: One Line or Two Lines?

    Honestly, looking the results, no conclusion can be drawn beyond the fact that one piece of code produces different results than another.

    There are many many optimizations that the compiler can perform: for example:

    Dim d as double = 1

    produces different assembly from:

    Dim d as double = 53.4

    This is a 'special' case scenario; just as casting is a special case scenario, and has nothing to do with the number of lines of code typed into the IDE. It doesn't necessarily apply in this case, but the point is that the quantity of code we write has absolutely no correlation with performance. Indeed, more lines of IDE code can result in a significant performance increase in some cases (my brush with this was going from a nice, compact routine to a horrible piece of lengthy code with many nested if/then statements).

    At this point, I'd like to say that I get 'opposite' results than the OP with the OP code - opposite in that the difference number of milliseconds out of a 5 second execution time for each loop is around 100. Essentially, the execution time is the same - this is in debug mode, verses release mode.

    A cursory glance at the generated (debug and release) assembly indicates that the 'two line' entry results in an additional line of assembly.

    While inline code can be very useful, it doesn't necessarily tell the whole story. The underlying assembly language is probably a better indicator of performance, since you will be able to see compiler optimizations (inlining and constant substitution, for example).

    Declaring a variable in a loop or outside a loop makes no difference - we can put that one to to rest, but all are welcome to prove (demonstrate?) that for themselves.

  22. #22
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    40,106

    Re: One Line or Two Lines?

    What's your point? Would you not look at this? If you found a difference, would you not wonder why? Surely you wouldn't take any difference and just pass it off as some kind of compiler optimization, nor would you find a difference and just ignore it. So what are you getting at?
    My usual boring signature: Nothing

  23. #23
    Powered By Medtronic dbasnett's Avatar
    Join Date
    Dec 2007
    Location
    Jefferson City, MO
    Posts
    9,897

    Re: One Line or Two Lines?

    the test is flawed.

    if the difference is troublesome the first place to start is to explain why all of the test of a certain type aren't identical.

    Code:
    	One	Two	
    	3786	3677	109
    			
    	3787	3683	104
    			
    	3787	3677	110
    			
    	3790	3678	112
    			
    	3783	3677	106
    			
    Average	3786.6	3678.4	108.2
    Median	3786.8	3677.5	109.3
    
    High	3790	3683	107
    Small	3783	3677	106
    StdDev	2.50998008	2.607680962
    57.07743279
    if the numbers were 4000 and 2000 it would be different.
    Last edited by dbasnett; Feb 16th, 2009 at 02:46 PM.
    My First Computer -- Documentation Link (RT?M) -- Using the Debugger -- Prime Number Sieve
    Counting Bits -- Subnet Calculator -- UI Guidelines -- >> SerialPort Answer <<

    "Those who use Application.DoEvents have no idea what it does and those who know what it does never use it." John Wein

  24. #24
    Powered By Medtronic dbasnett's Avatar
    Join Date
    Dec 2007
    Location
    Jefferson City, MO
    Posts
    9,897

    Re: One Line or Two Lines?

    Code:
            Dim stpw As New Stopwatch, i, z As Integer
            Const i1 As Integer = 1, iLoop As Integer = 500000000, tests As Integer = 5
            Dim results As New List(Of Long)
            For z = i1 To tests
                stpw.Start()
                For i = i1 To iLoop
                Next
                stpw.Stop()
                results.Add(stpw.ElapsedMilliseconds)
                stpw.Reset()
            Next
            For i = 0 To results.Count - 1
                Debug.WriteLine("'" & results(i).ToString)
            Next
    
            '1705
            '1632
            '1607
            '1605
            '1696
    shouldn't these results be identical????????
    Last edited by dbasnett; Feb 16th, 2009 at 03:39 PM.
    My First Computer -- Documentation Link (RT?M) -- Using the Debugger -- Prime Number Sieve
    Counting Bits -- Subnet Calculator -- UI Guidelines -- >> SerialPort Answer <<

    "Those who use Application.DoEvents have no idea what it does and those who know what it does never use it." John Wein

  25. #25
    Powered By Medtronic dbasnett's Avatar
    Join Date
    Dec 2007
    Location
    Jefferson City, MO
    Posts
    9,897
    My First Computer -- Documentation Link (RT?M) -- Using the Debugger -- Prime Number Sieve
    Counting Bits -- Subnet Calculator -- UI Guidelines -- >> SerialPort Answer <<

    "Those who use Application.DoEvents have no idea what it does and those who know what it does never use it." John Wein

  26. #26
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    40,106

    Re: One Line or Two Lines?

    Not sure what you are getting at. Are you suggesting that the differences we are seeing are just simple variation about a mean? That's not the case for the tests I posted, as the variation I was observing within a group was dwarfed by the variation I was observing between the two groups. The confidence intervals were never even close to overlapping. For instance, I was seeing a 10% difference between the means of the two groups in the second test (with release code), while the maximum variation within the group was around 0.5%
    My usual boring signature: Nothing

  27. #27
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    40,106

    Re: One Line or Two Lines?

    Having read the link, which you posted while I was writing that, I would argue that, while micro optimization is not going to make much of a difference in any business code, there are still two reasons to partake:

    1) You learn more about the language and how it works. Who knows how and when the knowledge will be of benefit, but the more you know, the better you will do.

    2) It's fun. If you don't think so, look at the list of people in this thread who put together tests of one thing or another and cited nothing more than curiosity.
    My usual boring signature: Nothing

  28. #28
    Powered By Medtronic dbasnett's Avatar
    Join Date
    Dec 2007
    Location
    Jefferson City, MO
    Posts
    9,897

    Re: One Line or Two Lines?

    the difference in the test, using the original numbers, was within the margin of error (twice the standard deviation?).
    My First Computer -- Documentation Link (RT?M) -- Using the Debugger -- Prime Number Sieve
    Counting Bits -- Subnet Calculator -- UI Guidelines -- >> SerialPort Answer <<

    "Those who use Application.DoEvents have no idea what it does and those who know what it does never use it." John Wein

  29. #29
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    40,106

    Re: One Line or Two Lines?

    I don't see that. In your post #23, you show the range and SD of the two groups. The SD in both cases was ~2.5, while the difference between the means was 108.2 That's 50x the SD, which is considerably larger than 2x.

    This one passes the Interocular Arm-Length Test, which is the most robust statistical test in existence.

    Edit: Not 50x, but 43x, which is still a big number.
    My usual boring signature: Nothing

  30. #30
    Powered By Medtronic dbasnett's Avatar
    Join Date
    Dec 2007
    Location
    Jefferson City, MO
    Posts
    9,897

    Re: One Line or Two Lines?

    the difference in each line was 100'ish and the SD of the entire set was 57.
    My First Computer -- Documentation Link (RT?M) -- Using the Debugger -- Prime Number Sieve
    Counting Bits -- Subnet Calculator -- UI Guidelines -- >> SerialPort Answer <<

    "Those who use Application.DoEvents have no idea what it does and those who know what it does never use it." John Wein

  31. #31
    PowerPoster SJWhiteley's Avatar
    Join Date
    Feb 2009
    Location
    South of the Mason-Dixon Line
    Posts
    2,256

    Re: One Line or Two Lines?

    Quote Originally Posted by Shaggy Hiker
    What's your point? Would you not look at this? If you found a difference, would you not wonder why? Surely you wouldn't take any difference and just pass it off as some kind of compiler optimization, nor would you find a difference and just ignore it. So what are you getting at?
    If you referring to my post...who said anything about 'ignoring it'? The 'point', is that the compiler does perform optimizations which you may not be aware of - is it the case in this situation? perhaps not, but you cannot dismiss that. Looking at the assembly code, it resulted in a single line of assembly code difference between the two large loops - yet two lines of IL code.

    That was an attempt to explain and examine the difference, even though it doesn't explain why Pradeep got faster times for the 'two line' loop verses the 'one line' loop.

    Additionally, the different results from different people demonstrate that we are examining the results from a flawed test. As dbasnett demonstrated, and raised the question, why are the results from the same loop so different?

    Quote Originally Posted by Pradeep1210
    Maybe it is a very small difference, but worth knowing why there is such a difference. It can't be due to external factors like OS doing some other background tasks during that time, since it seems to affect only one of them and not the other.
    I was just interested in knowing how the two lines are always faster than the single line code, though logically single line code should have performed better as the compiler has lesser overheads involved.
    How does the compiler favor 2 lines instead of the one line code even after having overheads of more instructions and memory?
    I would be curious about the scalability, Pradeep: what results do you get if you run the loops for 10 times the values you have given in the original post? Does it scale and give the same relative difference?

    I don't get the size of variation that you post; I posted your exact code into a new project.

  32. #32
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    40,106

    Re: One Line or Two Lines?

    Quote Originally Posted by dbasnett
    the difference in each line was 100'ish and the SD of the entire set was 57.
    You don't compare the SD of the entire set, but the error of each group. The question is whether an item of set A can reasonably be mistaken for an item of set B. In this case, with no overlap between the groups, that type of mistake can't be made. The two are significantly different by any test.

    @SJWhiteley: Ok, I understand you now, I think. Normally, when you see a difference in performance between two minor chunks of code, you need look no further than the IL, which I mentioned in my first post in this thread. The interesting point about this particular difference is that you can't explain the difference via IL alone. While I recognize that the conversion from IL to machine code is not simplistic, and ripe for optimization, in my experience, I have never before seen a question like this that required digging deeper than the IL, so for me, it is novel.

    As for the variations between runs: I didn't examine it carefully, but most people were running tests on different code, and everybody was running tests on different computers (of course). No absolute measurement, nor any single measurement, has any meaning. There are interrupts being handled by the OS at a level well below our code, and we can't predict the exact state of any particular run, which is why it is essential to run many times with very high iteration rates. The high iteration rates reduces the error in any one iteration to a negligible level (though it is not a random error, but shows a distinct bias high), while averaging multiple tests takes care of the variation between the tests as far as we care.
    My usual boring signature: Nothing

  33. #33
    PowerPoster SJWhiteley's Avatar
    Join Date
    Feb 2009
    Location
    South of the Mason-Dixon Line
    Posts
    2,256

    Re: One Line or Two Lines?

    Shaggy: you are right, you wouldn't normally need to go down to assembly level. In fact, it's not often that you need to go and look at IL... You brought up a good point that something like this is rarely necessary in business code - the impact is usually minimal.

    Then again, these are the sorts of things which bite us on the bum, so to speak. Although not relevant to this topic, IL code won't show when a compile in-lines a function to increase performance.

    And you are right - the IL cannot give a reason for a difference, and neither can the assembly. But it hints at a much smaller difference than what the OP is seeing, and indeed, would indicate a difference in the other direction.

    In any case, I suppose I'm just chucking ideas out there...code timing is actually a fickle thing. db, I think, has shown that the basis on which we are working is fundamentally flawed; in addition there isn'a a commonality between the posts with code - kind of like arguing which of us gets to work the quickest between two routes we may take (I think I'd beet all of y'all...).

  34. #34

    Thread Starter
    VB Addict Pradeep1210's Avatar
    Join Date
    Apr 2004
    Location
    Inside the CPU...
    Posts
    6,614

    Re: One Line or Two Lines?

    Quote Originally Posted by dbasnett
    the test is flawed.

    if the difference is troublesome the first place to start is to explain why all of the test of a certain type aren't identical.

    Code:
    	One	Two	
    	3786	3677	109
    			
    	3787	3683	104
    			
    	3787	3677	110
    			
    	3790	3678	112
    			
    	3783	3677	106
    			
    Average	3786.6	3678.4	108.2
    Median	3786.8	3677.5	109.3
    
    High	3790	3683	107
    Small	3783	3677	106
    StdDev	2.50998008	2.607680962
    57.07743279
    if the numbers were 4000 and 2000 it would be different.
    This is OK... but why is each individual result row of 2 lines test always faster than the one line test whatever way we test. Not even one result points the opposite?
    We would take statistical analysis only when the results are mixed. Isn't it? But here the speedometer always points towards 2 lines test and not once towards one line test.


    Pradeep
    Pradeep, Microsoft MVP (Visual Basic)
    Please appreciate posts that have helped you by clicking icon on the left of the post.
    "A problem well stated is a problem half solved." — Charles F. Kettering

    Read articles on My Blog101 LINQ SamplesJSON ValidatorXML Schema Validator"How Do I" videos on MSDNVB.NET and C# ComparisonGood Coding PracticesVBForums Reputation SaverString EnumSuper Simple Tetris Game


    (2010-2013)
    NB: I do not answer coding questions via PM. If you want my help, then make a post and PM me it's link. If I can help, trust me I will...

  35. #35
    Powered By Medtronic dbasnett's Avatar
    Join Date
    Dec 2007
    Location
    Jefferson City, MO
    Posts
    9,897

    Re: One Line or Two Lines?

    Code:
    Ctype
    
    Start Normal
    2/17/2009 8:48:28 AM
    ONE  	TWO  	DIFF  
    1936	2073	-137
    1968	1975	-7
    2002	1943	59
    1938	1971	-33
    1942	1954	-12
    1953	1955	-2
    1949	2077	-128
    2008	1983	25
    1978	1989	-11
    1973	2005	-32
    2/17/2009 8:49:07 AM
    
    
    Start Highest
    2/17/2009 8:47:11 AM
    ONE  	TWO  	DIFF  
    1836	1837	-1
    1853	1839	14
    1857	1847	10
    1834	1848	-14
    1845	1837	8
    1836	1843	-7
    1832	1835	-3
    1833	1833	0
    1836	1843	-7
    1840	1832	8
    2/17/2009 8:47:49 AM
    
    
    DirectCast
    
    Start Normal
    2/17/2009 8:50:20 AM
    ONE  	TWO  	DIFF  
    1964	2112	-148
    1989	2062	-73
    1996	2054	-58
    1968	2105	-137
    2004	2031	-27
    1987	2022	-35
    1960	2156	-196
    1992	2077	-85
    2012	2029	-17
    1964	2034	-70
    2/17/2009 8:51:00 AM
    
    Start Highest
    2/17/2009 8:51:44 AM
    ONE  	TWO  	DIFF  
    1837	1847	-10
    1838	1832	6
    1861	1833	28
    1835	1847	-12
    1840	1847	-7
    1835	1837	-2
    1834	1831	3
    1838	1838	0
    1836	1847	-11
    1834	1832	2
    2/17/2009 8:52:21 AM

    Code:
    Option Strict On : Option Explicit On
    Imports System.Threading
    Public Class Form1
        Private Sub Form1_Shown(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Shown
            Timer1.Interval = 1000
            Timer1.Start()
            Me.WindowState = FormWindowState.Minimized
        End Sub
        Dim t As Thread = New Thread(AddressOf test)
        Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
            Timer1.Stop()
            t.Priority = ThreadPriority.Highest
            Debug.WriteLine("Start " & t.Priority.ToString)
            t.Start()
        End Sub
        Private Sub test()
            Dim but As New Button
            DUT(DirectCast(but, Object))
        End Sub
        Private Sub DUT(ByVal sender As System.Object)
            Dim sw As New Stopwatch, senderName As String
            Dim one, two As Long
            Const loops As Integer = 20000000
            Debug.WriteLine(DateTime.Now.ToString)
            Debug.WriteLine("ONE  " & ControlChars.Tab & "TWO  " & ControlChars.Tab & "DIFF  ")
            For i As Integer = 1 To 10
                'one
                sw.Reset() : sw.Start()
                For j As Integer = 1 To loops
                    senderName = DirectCast(sender, Button).Name
                Next
                sw.Stop()
                one = sw.ElapsedMilliseconds
    
                'two
                sw.Reset() : sw.Start()
                For j As Integer = 1 To loops
                    Dim btn As Button = DirectCast(sender, Button)
                    senderName = btn.Name
                Next
                sw.Stop()
                two = sw.ElapsedMilliseconds
    
                Debug.WriteLine(one.ToString.PadRight(4, " "c) & ControlChars.Tab & _
                                two.ToString.PadRight(4, " "c) & ControlChars.Tab & _
                                (one - two).ToString)
            Next
            Debug.WriteLine(DateTime.Now.ToString)
        End Sub
    End Class
    My First Computer -- Documentation Link (RT?M) -- Using the Debugger -- Prime Number Sieve
    Counting Bits -- Subnet Calculator -- UI Guidelines -- >> SerialPort Answer <<

    "Those who use Application.DoEvents have no idea what it does and those who know what it does never use it." John Wein

  36. #36

    Thread Starter
    VB Addict Pradeep1210's Avatar
    Join Date
    Apr 2004
    Location
    Inside the CPU...
    Posts
    6,614

    Re: One Line or Two Lines?

    Quote Originally Posted by SJWhiteley
    ...
    I would be curious about the scalability, Pradeep: what results do you get if you run the loops for 10 times the values you have given in the original post? Does it scale and give the same relative difference?

    I don't get the size of variation that you post; I posted your exact code into a new project.
    I tried with increasing the loops to 10 times instead of 5. Here are the results:
    Code:
    One Line : 3812
    Two Lines: 3705
    One Line : 3818
    Two Lines: 3702
    One Line : 3807
    Two Lines: 3700
    One Line : 3808
    Two Lines: 3700
    One Line : 3809
    Two Lines: 3696
    One Line : 3806
    Two Lines: 3699
    One Line : 3811
    Two Lines: 3701
    One Line : 3808
    Two Lines: 3703
    One Line : 3810
    Two Lines: 3700
    One Line : 3809
    Two Lines: 3698
    Pradeep, Microsoft MVP (Visual Basic)
    Please appreciate posts that have helped you by clicking icon on the left of the post.
    "A problem well stated is a problem half solved." — Charles F. Kettering

    Read articles on My Blog101 LINQ SamplesJSON ValidatorXML Schema Validator"How Do I" videos on MSDNVB.NET and C# ComparisonGood Coding PracticesVBForums Reputation SaverString EnumSuper Simple Tetris Game


    (2010-2013)
    NB: I do not answer coding questions via PM. If you want my help, then make a post and PM me it's link. If I can help, trust me I will...

  37. #37
    PowerPoster SJWhiteley's Avatar
    Join Date
    Feb 2009
    Location
    South of the Mason-Dixon Line
    Posts
    2,256

    Re: One Line or Two Lines?

    Quote Originally Posted by Pradeep1210
    I tried with increasing the loops to 10 times instead of 5. Here are the results:
    I mean multiply your inner loop by 10, so you are running it for half a minute or so per loop.

    Basically, if it takes 3800ms for loop 1 and 3700 for loop 2, what would be the results for 1x the number of loops. We will get:

    Loop One: 38000 ms
    Loop Two: 37000 ms (1 second difference)

    or:

    Loop One: 38000 ms
    Loop Tow: 37900 ms (still a 100ms difference)

    or, something else.

    Personally, I don't get the same results as you at all - the results are all within 10mS or so on my PC, so don't see a problem.

    Obviously, you do see a difference; the IL and assembly code would contradict your evidence, so we'd have to determine a pattern for the results to see if there's potentially another reason for the discrepancy.
    Last edited by SJWhiteley; Feb 17th, 2009 at 12:08 PM.

  38. #38
    Powered By Medtronic dbasnett's Avatar
    Join Date
    Dec 2007
    Location
    Jefferson City, MO
    Posts
    9,897

    Re: One Line or Two Lines?

    i can't replicate the results that pradeep had. it is still my opinion that the experiment is flawed.

    in post #24 i think i showed that.

    Code:
    'Start Normal
    '2/17/2009 2:13:56 PM
    'BaseLine
    '288
    '300
    '293
    '292
    '287
    'Test
    '509
    '497
    '496
    '487
    '510
    
    'Start Highest
    '2/17/2009 2:14:07 PM
    'BaseLine
    '300
    '289
    '283
    '284
    '284
    'Test
    '479
    '478
    '475
    '476
    '475
    Option Strict On : Option Explicit On : Option Infer Off
    Imports System.Threading
    Public Class Form1
        Dim stpw As New Stopwatch, i, z As Integer
        Const i1 As Integer = 1, iLoop As Integer = 50000000, tests As Integer = 5
        Dim results As New List(Of Long)
        Private Sub test()
            Debug.WriteLine("'" & DateTime.Now.ToString)
            Debug.WriteLine("'BaseLine")
            BaseLine()
            Debug.WriteLine("'Test")
            UnitTest()
        End Sub
        Private Sub BaseLine()
            results.Clear()
            For z = i1 To tests
                stpw.Start()
                For i = i1 To iLoop
                    'shouldn't .ElapsedMilliseconds be the same???????
                Next
                stpw.Stop()
                results.Add(stpw.ElapsedMilliseconds)
                stpw.Reset()
            Next
            For i = 0 To results.Count - 1
                Debug.WriteLine("'" & results(i).ToString)
            Next
        End Sub
        Dim foo As Double
        Private Sub UnitTest()
            results.Clear()
            For z = i1 To tests
                stpw.Start()
                For i = i1 To iLoop
                    foo = CDbl(i)
                Next
                stpw.Stop()
                results.Add(stpw.ElapsedMilliseconds)
                stpw.Reset()
            Next
            For i = 0 To results.Count - 1
                Debug.WriteLine("'" & results(i).ToString)
            Next
        End Sub
        Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
            Dim t As Thread = New Thread(AddressOf test)
            Timer1.Stop()
            If CheckBox1.Checked Then t.Priority = ThreadPriority.Highest
            Debug.WriteLine("'Start " & t.Priority.ToString)
            t.Start()
        End Sub
        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            Timer1.Interval = 1000
            If Not Timer1.Enabled Then
                Debug.WriteLine("")
                Timer1.Start()
            End If
        End Sub
    End Class
    Last edited by dbasnett; Feb 17th, 2009 at 03:23 PM.
    My First Computer -- Documentation Link (RT?M) -- Using the Debugger -- Prime Number Sieve
    Counting Bits -- Subnet Calculator -- UI Guidelines -- >> SerialPort Answer <<

    "Those who use Application.DoEvents have no idea what it does and those who know what it does never use it." John Wein

  39. #39

    Thread Starter
    VB Addict Pradeep1210's Avatar
    Join Date
    Apr 2004
    Location
    Inside the CPU...
    Posts
    6,614

    Re: One Line or Two Lines?

    Quote Originally Posted by SJWhiteley
    I mean multiply your inner loop by 10, so you are running it for half a minute or so per loop.

    Basically, if it takes 3800ms for loop 1 and 3700 for loop 2, what would be the results for 1x the number of loops. We will get:

    Loop One: 38000 ms
    Loop Two: 37000 ms (1 second difference)

    or:

    Loop One: 38000 ms
    Loop Tow: 37900 ms (still a 100ms difference)

    or, something else.

    Personally, I don't get the same results as you at all - the results are all within 10mS or so on my PC, so don't see a problem.

    Obviously, you do see a difference; the IL and assembly code would contradict your evidence, so we'd have to determine a pattern for the results to see if there's potentially another reason for the discrepancy.
    Multiplied the inner loops by 10 (increased one zero). Here are the results now:
    Code:
    One Line : 36727
    Two Lines: 36702
    One Line : 36713
    Two Lines: 36713
    One Line : 36714
    Two Lines: 36709
    The thread 0x17c has exited with code 0 (0x0).
    One Line : 36702
    Two Lines: 36708
    One Line : 36700
    Two Lines: 36707
    One Line : 36704
    Two Lines: 36702
    One Line : 36699
    Two Lines: 36708
    One Line : 36711
    Two Lines: 36705
    One Line : 36737
    Two Lines: 36718
    One Line : 36709
    Two Lines: 36716
    Amazingly the difference seems to be reducing instead of increasing
    Pradeep, Microsoft MVP (Visual Basic)
    Please appreciate posts that have helped you by clicking icon on the left of the post.
    "A problem well stated is a problem half solved." — Charles F. Kettering

    Read articles on My Blog101 LINQ SamplesJSON ValidatorXML Schema Validator"How Do I" videos on MSDNVB.NET and C# ComparisonGood Coding PracticesVBForums Reputation SaverString EnumSuper Simple Tetris Game


    (2010-2013)
    NB: I do not answer coding questions via PM. If you want my help, then make a post and PM me it's link. If I can help, trust me I will...

  40. #40
    Frenzied Member MaximilianMayrhofer's Avatar
    Join Date
    Aug 2007
    Location
    IM IN YR LOOP
    Posts
    2,001

    Re: One Line or Two Lines?

    Which just means that the first one has a fixed overhead associated with it. The more loops you run, the less significant the overhead to the total time taken.

Page 1 of 2 12 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width