424,667 Members | 2,214 Online
Need help? Post your question and get tips & solutions from a community of 424,667 IT Pros & Developers. It's quick & easy.

# Access 2003: The Second Loop is the Faster

 P: n/a II first noticed this phenomenon in Access 2003. Simply stated it is: The second loop is faster than the first loop. That is if we test: Not (a Or b) against (Not a) And (Not b) in a loop of ten million iterations we will find that the condition we test first is the slower of the two, no matter which one that is. Now clearly "Not (a Or b)" should be faster than "(Not a) And (Not b)" as we are doing two operations against three. And it is. But if we were to test (in the same module) Not (a Or b) first and (Not a) And (Not b) second we might conclude the opposite. A simple code test is shown below. Can you duplicate my results? Do you have an opinion? Have I made an error in logic? Private Declare Function GetTickCount Lib "kernel32" () As Long Private Const Iterations As Long = 10000000 Sub AlgebraicLogic1() Dim t(2) As Long Dim y As Long Dim z As Long Dim a As Boolean Dim b As Boolean Dim c As Boolean t(0) = GetTickCount For y = 1 To Iterations c = (Not a) And (Not b) Next y t(0) = GetTickCount - t(0) t(1) = GetTickCount For z = 1 To Iterations c = Not (a Or b) Next z t(1) = GetTickCount - t(1) Debug.Print 1, t(0), t(1), t(1) / t(0) End Sub Sub AlgebraicLogic2() Dim t(2) As Long Dim y As Long Dim z As Long Dim a As Boolean Dim b As Boolean Dim c As Boolean t(0) = GetTickCount For y = 1 To Iterations c = Not (a Or b) Next y t(0) = GetTickCount - t(0) t(1) = GetTickCount For z = 1 To Iterations c = (Not a) And (Not b) Next z t(1) = GetTickCount - t(1) Debug.Print 2, t(0), t(1), t(1) / t(0) End Sub 1 541 301 0.55637707948244 2 460 331 0.719565217391304 1 521 301 0.577735124760077 2 471 320 0.679405520169851 1 521 310 0.595009596928983 2 461 320 0.6941431670282 1 521 310 0.595009596928983 2 491 331 0.674134419551935 Mar 15 '06 #1
10 Replies

 P: n/a My results show Not(A Or B) to be faster each time, whether it is run first or second. 1 484 453 0.935950413223141 2 453 484 1.06843267108168 1 484 453 0.935950413223141 2 453 469 1.03532008830022 1 484 454 0.93801652892562 2 453 484 1.06843267108168 -- Wayne Morgan MS Access MVP "Lyle Fairfield" wrote in message news:11**********************@p10g2000cwp.googlegr oups.com... II first noticed this phenomenon in Access 2003. Simply stated it is: The second loop is faster than the first loop. That is if we test: Not (a Or b) against (Not a) And (Not b) in a loop of ten million iterations we will find that the condition we test first is the slower of the two, no matter which one that is. Now clearly "Not (a Or b)" should be faster than "(Not a) And (Not b)" as we are doing two operations against three. And it is. But if we were to test (in the same module) Not (a Or b) first and (Not a) And (Not b) second we might conclude the opposite. A simple code test is shown below. Can you duplicate my results? Do you have an opinion? Have I made an error in logic? Private Declare Function GetTickCount Lib "kernel32" () As Long Private Const Iterations As Long = 10000000 Sub AlgebraicLogic1() Dim t(2) As Long Dim y As Long Dim z As Long Dim a As Boolean Dim b As Boolean Dim c As Boolean t(0) = GetTickCount For y = 1 To Iterations c = (Not a) And (Not b) Next y t(0) = GetTickCount - t(0) t(1) = GetTickCount For z = 1 To Iterations c = Not (a Or b) Next z t(1) = GetTickCount - t(1) Debug.Print 1, t(0), t(1), t(1) / t(0) End Sub Sub AlgebraicLogic2() Dim t(2) As Long Dim y As Long Dim z As Long Dim a As Boolean Dim b As Boolean Dim c As Boolean t(0) = GetTickCount For y = 1 To Iterations c = Not (a Or b) Next y t(0) = GetTickCount - t(0) t(1) = GetTickCount For z = 1 To Iterations c = (Not a) And (Not b) Next z t(1) = GetTickCount - t(1) Debug.Print 2, t(0), t(1), t(1) / t(0) End Sub 1 541 301 0.55637707948244 2 460 331 0.719565217391304 1 521 301 0.577735124760077 2 471 320 0.679405520169851 1 521 310 0.595009596928983 2 461 320 0.6941431670282 1 521 310 0.595009596928983 2 491 331 0.674134419551935 Mar 15 '06 #2

 P: n/a On 15 Mar 2006 05:14:03 -0800, "Lyle Fairfield" wrote: Interesting phenomenon. Purely speculating: it could be that some variables can be held in fast registers (on the CPU), while others go in a bit slower cache memory. -Tom. II first noticed this phenomenon in Access 2003. Simply stated it is:The second loop is faster than the first loop.That is if we test:Not (a Or b) against (Not a) And (Not b)in a loop of ten million iterations we will find that the condition wetest first is the slower of the two, no matter which one that is.Now clearly "Not (a Or b)" should be faster than "(Not a) And (Not b)"as we are doing two operations against three. And it is.But if we were to test (in the same module) Not (a Or b) first and (Nota) And (Not b) second we might conclude the opposite.A simple code test is shown below.Can you duplicate my results?Do you have an opinion?Have I made an error in logic?Private Declare Function GetTickCount Lib "kernel32" () As LongPrivate Const Iterations As Long = 10000000Sub AlgebraicLogic1()Dim t(2) As LongDim y As LongDim z As LongDim a As BooleanDim b As BooleanDim c As Booleant(0) = GetTickCountFor y = 1 To Iterationsc = (Not a) And (Not b)Next yt(0) = GetTickCount - t(0)t(1) = GetTickCountFor z = 1 To Iterationsc = Not (a Or b)Next zt(1) = GetTickCount - t(1)Debug.Print 1, t(0), t(1), t(1) / t(0)End SubSub AlgebraicLogic2()Dim t(2) As LongDim y As LongDim z As LongDim a As BooleanDim b As BooleanDim c As Booleant(0) = GetTickCountFor y = 1 To Iterationsc = Not (a Or b)Next yt(0) = GetTickCount - t(0)t(1) = GetTickCountFor z = 1 To Iterationsc = (Not a) And (Not b)Next zt(1) = GetTickCount - t(1)Debug.Print 2, t(0), t(1), t(1) / t(0)End Sub 1 541 301 0.55637707948244 2 460 331 0.719565217391304 1 521 301 0.577735124760077 2 471 320 0.679405520169851 1 521 310 0.595009596928983 2 461 320 0.6941431670282 1 521 310 0.595009596928983 2 491 331 0.674134419551935 Mar 15 '06 #3

 P: n/a On Wed, 15 Mar 2006 13:50:24 GMT, "Wayne Morgan" wrote: My results show Not(A Or B) to be faster each time, whether it is run firstor second. 1 484 453 0.935950413223141 2 453 484 1.06843267108168 1 484 453 0.935950413223141 2 453 469 1.03532008830022 1 484 454 0.93801652892562 2 453 484 1.06843267108168 Just to confuse matters, my results are the opposite of yours. ie (Not a) And (Not b) is always quicker. 1 578 828 1.43252595155709 2 828 578 0.698067632850242 1 563 843 1.49733570159858 2 844 578 0.684834123222749 1 563 843 1.49733570159858 2 844 563 0.667061611374408 1 578 828 1.43252595155709 2 828 578 0.698067632850242 1 563 843 1.49733570159858 2 829 578 0.697225572979493 Wayne Gillespie Gosford NSW Australia Mar 15 '06 #4

 P: n/a Yup, but both of our results are more consistent than Lyle's (within a set, between sets his are still fairly consistent). It appears that Lyle's results for #2 may have been pulling the previous results from cache somehow. 1 541 301 2 460 331 Note that the 541 and 331 are for the same calculation. However, the 301 and 460 are also, so I don't understand the wide variance there. I suspect that without knowing the internal structure of the CPUs, all of this is just supposition. -- Wayne Morgan MS Access MVP Mar 15 '06 #5

 P: n/a playing it loose and fast with the word "interesting" there, tom ;p - but that said, i'd bet your right. i'm sure it has to do with the way the variables are cached... it's the only thing that makes sense. Mar 15 '06 #6

 P: n/a The two gate Not (a Or b) is consistently the faster on my PC (see below for representative sample). 1 751 691 0.920106524633822 1 741 701 0.946018893387314 1 751 691 0.920106524633822 2 711 731 1.028129395218 2 711 731 1.028129395218 2 701 731 1.04279600570613 -- Terry Kreft "Lyle Fairfield" wrote in message news:11**********************@p10g2000cwp.googlegr oups.com... II first noticed this phenomenon in Access 2003. Simply stated it is: The second loop is faster than the first loop. That is if we test: Not (a Or b) against (Not a) And (Not b) in a loop of ten million iterations we will find that the condition we test first is the slower of the two, no matter which one that is. Now clearly "Not (a Or b)" should be faster than "(Not a) And (Not b)" as we are doing two operations against three. And it is. But if we were to test (in the same module) Not (a Or b) first and (Not a) And (Not b) second we might conclude the opposite. A simple code test is shown below. Can you duplicate my results? Do you have an opinion? Have I made an error in logic? Private Declare Function GetTickCount Lib "kernel32" () As Long Private Const Iterations As Long = 10000000 Sub AlgebraicLogic1() Dim t(2) As Long Dim y As Long Dim z As Long Dim a As Boolean Dim b As Boolean Dim c As Boolean t(0) = GetTickCount For y = 1 To Iterations c = (Not a) And (Not b) Next y t(0) = GetTickCount - t(0) t(1) = GetTickCount For z = 1 To Iterations c = Not (a Or b) Next z t(1) = GetTickCount - t(1) Debug.Print 1, t(0), t(1), t(1) / t(0) End Sub Sub AlgebraicLogic2() Dim t(2) As Long Dim y As Long Dim z As Long Dim a As Boolean Dim b As Boolean Dim c As Boolean t(0) = GetTickCount For y = 1 To Iterations c = Not (a Or b) Next y t(0) = GetTickCount - t(0) t(1) = GetTickCount For z = 1 To Iterations c = (Not a) And (Not b) Next z t(1) = GetTickCount - t(1) Debug.Print 2, t(0), t(1), t(1) / t(0) End Sub 1 541 301 0.55637707948244 2 460 331 0.719565217391304 1 521 301 0.577735124760077 2 471 320 0.679405520169851 1 521 310 0.595009596928983 2 461 320 0.6941431670282 1 521 310 0.595009596928983 2 491 331 0.674134419551935 Mar 15 '06 #7

 P: n/a My results are the same as Waynes 1 468 454 0.97008547008547 2 437 485 1.10983981693364 2 437 485 1.10983981693364 1 485 453 0.934020618556701 Mar 15 '06 #8

 P: n/a I'm testing on a "Centrino Mobile Technology" laptop. I have no idea if this might be pertinent. Mar 15 '06 #9

 P: n/a Tom van Stiphout wrote in news:gr********************************@4ax.com: Interesting phenomenon. Purely speculating: it could be that some variables can be held in fast registers (on the CPU), while others go in a bit slower cache memory. I would be interested to know if running the first loop twice will result in similar speeds for the second pass of Loop 1 and Loop 2. I have always thought there there's sometimes a certain overhead for getting VBA code started, even when it's fully compiled. What may be happening is that this overhead is being absorbed during the first loop, by something that the first loop is initializing that doesn't need to be re-initialized in the second loop. -- David W. Fenton http://www.dfenton.com/ usenet at dfenton dot com http://www.dfenton.com/DFA/ Mar 15 '06 #10

 P: n/a On 15 Mar 2006 09:36:19 -0800, "Lyle Fairfield" wrote: Check the EAX register! -Tom. I'm testing on a "Centrino Mobile Technology" laptop. I have no idea ifthis might be pertinent. Mar 16 '06 #11

### This discussion thread is closed

Replies have been disabled for this discussion.