Speeding up code: Removing invariants from loops.

User avatar
ChrisGreaves
PlutoniumLounger
Posts: 15636
Joined: 24 Jan 2010, 23:23
Location: brings.slot.perky

Speeding up code: Removing invariants from loops.

Post by ChrisGreaves »

I don't know what I was thinking; for years I've been telling folks to take invariant calculations out of loops.
OLD:

Code: Select all

For Each strP In rng.Paragraphs
    Call strStatusBar("Loading " & Format(100 * (strP.Range.Start / ActiveDocument.Characters.Count), "##0.000") & "%")
NEW:

Code: Select all

Dim lngCharCount As Long
lngCharCount = ActiveDocument.Characters.Count
For Each strP In rng.Paragraphs
    Call strStatusBar("Loading " & Format(100 * (strP.Range.Start / lngCharCount), "##0") & "%")
Compare the two chunks of code above; I've been waiting for up to two minutes each shot to get statistics on a 20,000 word essay.
The new code flashes by so quickly I almost don't get time to read the formatted string in the Statusbar!
I stared at the 3-decimal places in the Statusbar string, decided to get rid of them by changing the format string, and found the call to ActiveDocument.Characters.Count right there inside the loop.
That has prompted me to search my code database looking for all other occurences of ActiveDocument.Characters. and similar constructs.
There's nothing heavier than an empty water bottle

User avatar
agibsonsw
SilverLounger
Posts: 2403
Joined: 05 Feb 2010, 22:21
Location: London ENGLAND

Re: Speeding up code: Removing invariants from loops.

Post by agibsonsw »

I'm confused. lngCharCount will be an invariant so how can Characters.Count appear within the (2nd) loop?
"I'm here to save your life. But if I'm going to do that, I'll need total uninanonynymity." Me Myself & Irene.

User avatar
HansV
Administrator
Posts: 78524
Joined: 16 Jan 2010, 00:14
Status: Microsoft MVP
Location: Wageningen, The Netherlands

Re: Speeding up code: Removing invariants from loops.

Post by HansV »

Assuming that you don't modify the document within the loop, the character count (which has been calculated just before the loop and stored in lngCharCount) will remain the same, so it's legitimate to use lngCharCount within the loop.
Best wishes,
Hans