By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
424,667 Members | 2,214 Online
Bytes IT Community
+ Ask a Question
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
Share this Question
Share on Google+
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" <ly***********@aim.com> 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"
<ly***********@aim.com> 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 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 #3

P: n/a
On Wed, 15 Mar 2006 13:50:24 GMT, "Wayne Morgan"
<co***************************@hotmail.com> wrote:
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

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" <ly***********@aim.com> 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 <no*************@cox.net> 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"
<ly***********@aim.com> wrote:

Check the EAX register!
-Tom.

I'm testing on a "Centrino Mobile Technology" laptop. I have no idea if
this might be pertinent.


Mar 16 '06 #11

This discussion thread is closed

Replies have been disabled for this discussion.