• Performance discrepancy (Word 2003)

    • This topic has 9 replies, 3 voices, and was last updated 20 years ago.
    Author
    Topic
    #418206

    While experimenting with some new code, I pinpointed a particular procedure that was causing a bottleneck. On a 30-page document with about 500 paragraphs, it was taking nearly 10 seconds to run.

    After trying all manner of things to figure out what the cause of the delay was, I’m stuck. The problem isn’t that the code is slow — it actually isn’t. Running the Sub directly from the IDE, or directly from the Macros (Alt-F8) dialog results in completely acceptable performance for my purposes (about 1 sec). The problem is that whenever the Sub is run (it’s actually a function that’s part of a bunch of other stuff, but that’s not important) from a keybinding or from a toolbar button, it slows .. way … down.

    I’d be interested in finding out if (a). anyone can reproduce this given the code below, and (. if anyone has any ideas what’s going on and how to address it.

    Sub BuildParaDataTable()
    Dim doc As Document
    Set doc = ActiveDocument
    
    Dim k As Long
    Dim j As Long
    Dim para As Paragraph
    Dim vData() As Variant
    Dim col As Collection
    
    ReDim vData(1 To doc.Paragraphs.Count)
    
    k = 1
    For Each para In doc.Paragraphs
        Set col = New Collection
        With col
            .Add Key:="index", Item:=k
            .Add Key:="text", Item:=Left(para.Range.Text, para.Range.Characters.Count - 1)
            ' The following line is the slow one (see below)'----
            .Add Key:="style", Item:=Split(para.Style.NameLocal, ",")(0) '<--  
            .Add Key:="para", Item:=para
            .Add Key:="ofstyleindex", Item:=1
        End With
        For j = k - 1 To 1 Step -1
            If vData(j)("style") = col("style") Then
                ' Do some other stuff
                Exit For
            End If
        Next j
        Set vData(k) = col
        Set col = Nothing
        k = k + 1
    Next para
    MsgBox vData(10)("index")
    'BuildParaDataTable = vData
    
    End Sub
    

    The only line that seems to have any significant effect on the performance is the one I’ve noted in the code itself. I first suspected that maybe it was the repeated Split() calls, but if I change the line to the following, it’s not any faster:

    .Add Key:="style", Item:=para.Style.NameLocal
    

    I would be willing to accept that this particular experimental code was just inefficient, but it’s killing me that it’s only slow when I run it from a toolbar or a keybinding (or from another macro that’s called in one of those two ways). Hoping another Lounger might be able to provide some insight.

    I’ve provided a sample document that illustrates the behavior nicely if you run this macro on it.

    Any suggestions are welcome and appreciated.

    Viewing 0 reply threads
    Author
    Replies
    • #940503

      Whether I run it using F5 in the VBE or a new toolbar button I get approximately the same result. (I didn’t time it, but any difference was not noticeable.)

      Added: I’m using Word 2002 — perhaps this problem is a new feature of Word 2003?

      • #940507

        Thanks Jefferson, I’ll see if I can find a 2002 machine to try it on.

        • #940522

          I’m also 2002 and, like Jefferson, I get the same fast (1 sec. or less) performance whether I call it directly or with a toolbar button.

          • #940542

            I tried it on a different Word 2003 machine and get the same results as you guys. Then I tried unloading all Add-ins, and even a fresh Normal, to no avail. From the Task manager, I can see that when I go from the toolbar button, my CPU spikes to 100% and stays there for 6-8 seconds. Directly from the IDE, it barely breaks 75%, and only for a second.

            If it’s only this slow on my machine, that’s fine, but it’s going to drive me nuts until I figure out why. Argh.

            • #940566

              Perhaps rename Normal.dot temporarily and test again. I’m beginning to think that the template might have a problem.

            • #940570

              Yeah, tried that, along with Safe mode. Also tried it on the same machine as a different user, with no luck. Will keep trying …

            • #940593

              I had been thinking that maybe something else was running either before or after — maybe some antivirus scan or something, but when I tried the following code, the status bar showed that running from a toolbar just incremented more slowly. Very strange stuff.

              Sub TestArray()
              Dim v As Variant
              Dim para As Paragraph
              Dim doc As Document
              Dim k As Integer
              Set doc = ActiveDocument
              ReDim v(doc.Paragraphs.Count)
              k = 1
              For Each para In doc.Paragraphs
                  StatusBar = CStr(k)
                  v(k) = para.Style.NameLocal
                  k = k + 1
              Next para
              MsgBox "Done"
              End Sub
              

              It definitely seems to have something to do with the para property lookup. Some properties I tried (like para.Creator or para.IsStyleSepartor) resulted in no performance difference. But others, like para.LeftIndent displayed the same lag from a toolbar.

            • #940816

              My latest bizarre discovery on this is that if I activate or launch a different window, the performance lag goes away. For example, inserting a line to launch notepad (as shown below) does the trick. Alternately, activating a different open document works as well. This is quite a mystery, but I’ll keep plugging at it.

              Sub BuildParaDataTable()
              Dim doc As Document
              Set doc = ActiveDocument
              
              Dim k As Long
              Dim j As Long
              Dim para As Paragraph
              Dim vData() As Variant
              Dim col As Collection
              ReDim vData(1 To doc.Paragraphs.Count)
              Shell "notepad.exe" 
              k = 1
              For Each para In doc.Paragraphs
                  Set col = New Collection
                  With col
                      .Add Key:="index", Item:=k
                      .Add Key:="text", Item:=Left(para.Range.Text, para.Range.Characters.Count - 1)
                      ' The following line is the slow one (see below)'----
                      .Add Key:="style", Item:=Split(para.Style.NameLocal, ",")(0) '<--  
                      .Add Key:="para", Item:=para
                      .Add Key:="ofstyleindex", Item:=1
                  End With
                  For j = k - 1 To 1 Step -1
                      If vData(j)("style") = col("style") Then
                          ' Do some other stuff
                          Exit For
                      End If
                  Next j
                  Set vData(k) = col
                  Set col = Nothing
                  k = k + 1
              Next para
              MsgBox vData(10)("index")
              
              End Sub
              
            • #940844

              Well, I still don’t know why it’s happening, but I now have a workaround. Hopefully if someone else encounters this issue, this thread will save them some misery.

              Deactivating the active window seems to solve the problem (the reactivating it). I’ve done that with the following code:

              Dim lstate As Long
              With ActiveWindow
                  lstate = .WindowState
                  .WindowState = wdWindowStateMinimize
                  .WindowState = lstate
              End With
              

              The only explantion I can come up with is that this is somehow related to the fact that I’m using a Tablet PC, and some process somewhere is monitoring active windows, possibly to be ready to pop up a handy stylus input panel. I may be totally wrong on this, but I’m sick of thinking about it. At any rate, I’ve got a usable, if kludgy, workaround.

              Thanks for listening.

    Viewing 0 reply threads
    Reply To: Performance discrepancy (Word 2003)

    You can use BBCodes to format your content.
    Your account can't use all available BBCodes, they will be stripped before saving.

    Your information: