Author: NetworkAdminKB.com
Created: 2008-10-22
Modified: 2009-01-03
So you want to optimize your VBScript code to increase performance. I have written this article to explain the basic process and perform a demonstration. This will hopefully help you devise a way to performance test and performance optimize your code.
First, let’s define the various parts of Performance Testing and Performance Optimization.
Performance Testing is the process of running program code under a specific set of conditions and recording the result (the amount of time it takes to run). This is usually done with a static or random dataset. A static dataset may provide more predictable results during the test, while a random data may produce slightly varied results over a wider range of values.
Optimization is the process of identifying potential bottlenecks in the code and creating new code that will alleviate the bottleneck.
Performance Optimization is the process of Performance Testing current code, Optimizing the code, then Performance Testing the new optimized code. This can be done in a repeatable fashion until the desire performance is maximized.
Step 1 Performance Testing
It is highly recommended that you performance test specific pieces of code at a time, and not an entire program. The easiest pieces of code to performance test are individual procedures. Use the following process to create your first Performance Test.
1) Create a New VBScript file (codetester.vbs)
2) At the top of the codetester.vbs file type the following line. This will help identify programming issues when isolating a procedure from a whole program.
a. Option Explicit
3) Select a suitable procedure from your code to test and place codetester.vbs file.
4) Place the following code at the bottom of the codetester.vbs file.
Dim x, z, intStart, intStop
z = 100000
intStart = Timer
For x = 1 to z
'Call your procedure here
Next 'x
intStop = Timer
Wscript.Echo intStop - intStart
5) Add a call to your procedure inside the For Next Loop as indicated
6) Add any support Constants, variables, etc that may be needed for your Procedure to run in this isolated fashion. Good programming techniques greatly aid in being able to performance test sections of code.
7) Run the code one time.
8) View the timed results. If the results take less than 5 seconds to process, then increase the value of Z until the test runs for at least 5 seconds. If the test runs for longer than 1 minute you may want to reduce the value of Z so that the test runs in under a minute, but keep the value of Z to a minimum of about 1000.
a. This is done so that a meaningful comparison can be done against optimized code later. The time difference between optimized and un-optimized code will become greater the long it is run. This simplifies the comparison for the “optimized” code.
9) Run the code between 3-30 times and compute an average for the number of runs.
a. Statistically you need 30 runs so that any deviation can be standardized when using random datasets, but usually 3-5 runs is sufficient for our purposes.
Step 2 Optimize the Code
This can be tricky and overwhelming if you are unfamiliar with the internal workings VBScript. You will probably need to learn about specific properties of VBScript to help you determine what are and are not good performance optimizations.
After you learn the general performance pitfalls of VBScript you will need to focus on your algorithms. In general you should have an idea about how to improve the existing algorithm then test it to see if it works. The key here isn’t so much that you get it right, because even if you get it wrong you will learn what NOT to do in the future.
Common VBScript Performance Penalties
1) Creating and using Objects in VBScript is very slow. Look for ways to do the same thing without using an object.
a. For example the Dictionary Object may not be needed and an array or a custom written Class may work with greater speed.
b. If you must create the object do so only once at a global level and pass the object into any procedure using ByRef.
2) Loops are the enemy of performance
a. Exit loops early when appropriate. This is commonly called a “short circuit.”
i. To exit a For Next Loop use “Exit For”.
ii. To exit a Do LOOP use “Exit Do”
iii. To exit a While Loop use “WEnd”
b. Do multiple items in one loop, instead of performing separate loops.
i. The trade off here may be ease of design or implementation
c. Avoid loops if possible.
3) Arrays
a. Pass an array to a procedure using ByRef and not ByVal. ByVal will copy the array in memory which will slow performance.
b. Short circuit all array searches when the item is found.
4) Sorting
a. Quicksort has the best overall performance in VBScript. Find a good quick sort routine and use it any time sorting is needed.
5) Avoid using the following functions because they are very slow in VBScript
a. Eval
b. StrComp
c. CreateObject
d. GetObject
Step 3 Performance Optimization
After you have developed the new function you will need to test it for performance and compare it against the original function. To do this, follow the same general procedure outlined in Step 1 above.
Compare the results and determine which algorithm provides the best results.
Example Code for Performance Optimization
Option Explicit
'********************************************************************
'*
'* Function blnStrComp
'*
'* Purpose: Returns a Boolean indicating if the strings provided are
'* equal based on case sensitive or case insensitive
'* comparison. Numbers are converted to strings for
'* comparison.
'*
'* Input: strComp1 A string to compare with strComp2
'* strComp2 A string to compare with strComp1
'* blnCase A Boolean indicating case sensitive comparisons.
'* True = Case Sensitive comparison
'* False = Case Insensitive comparison (Default)
'*
'* Notes: UCase and LCase convert numbers to strings for comparison
'*
'* Output: Returns a Boolean indicating if the strings provided are
'* equal based on case sensitive or case insensitive
'* comparison.
'* True = The strings are equal
'* False = The strings are not equal.
'*
'********************************************************************
Function blnStrComp(ByVal strComp1, ByVal strComp2, ByVal blnCase)
'Version 1.0 2008-05-18
Select Case StrComp(strComp1, strComp2, ReturnCaseComparisonValue(blnCase))
Case 0
blnStrComp = True
Case Null, -1, 1
blnStrComp = False
Case Else
'Return Default Value
blnStrComp = False
End Select 'StrComp(strComp1, strComp2, ReturnCaseComparisonValue(blnCase))
End Function 'blnStrComp
'********************************************************************
'*
'* Function ReturnCaseComparisonValue
'*
'* Purpose: Returns the proper VB String Comparison Constant based on
'* the provided Boolean in blnCase
'*
'* Input: blnCase A Boolean indicating case sensitive comparisons.
'* True = Case Sensitive comparison
'* False = Case Insensitive comparison (Default)
'*
'* Output: Returns the proper VB String Comparison Constant based on
'* the provided Boolean in blnCase.
'* vbBinaryCompare 0 Perform a binary (case sensitive) comparison.
'* vbTextCompare 1 Perform a textual (case insensitive) comparison.
'* Returns vbTextCompare if blnCase is anything other than True
'* (i.e. Empty, Null, a String, etc).
'*
'********************************************************************
Function ReturnCaseComparisonValue(ByVal blnCase)
'Version 1.0 2008-05-18
Select Case blnCase
Case True
'vbBinaryCompare provides case sensitive comparison
ReturnCaseComparisonValue = vbBinaryCompare
Case False
'vbTextCompare provides case insensitive comparison
ReturnCaseComparisonValue = vbTextCompare
Case Else
'Return Default Setting.
ReturnCaseComparisonValue = vbTextCompare
End Select 'blnCase
End Function 'ReturnCaseComparisonValue
'********************************************************************
'*
'* Function blnStrCompV2
'*
'* Purpose: Returns a Boolean indicating if the strings provided are
'* equal based on case sensitive or case insensitive
'* comparison. Numbers are converted to strings for
'* comparison.
'*
'* Input: strComp1 A string to compare with strComp2
'* strComp2 A string to compare with strComp1
'* blnCase A Boolean indicating case sensitive comparisons.
'* True = Case Sensitive comparison
'* False = Case Insensitive comparison (Default)
'*
'* Output: Returns a Boolean indicating if the strings provided are
'* equal based on case sensitive or case insensitive
'* comparison.
'* True = The strings are equal
'* False = The strings are not equal.
'*
'* Notes: UCase and LCase convert numbers to strings for comparison
'*
'* Changes:
'* 2008-05-29: Complete re-write not using StrComp function to
'* improve speed.
'********************************************************************
Function blnStrCompV2(ByVal strComp1, ByVal strComp2, ByVal blnCase)
'Version 2.0 2008-05-29
Select Case blnCase
Case True
'case sensitive comparison
blnStrCompV2 = CBool(strComp1 = strComp2)
Case False
'case insensitive comparison
blnStrCompV2 = CBool(UCase(strComp1) = UCase(strComp2))
Case Else
'Default case insensitive comparison
blnStrCompV2 = CBool(UCase(strComp1) = UCase(strComp2))
End Select 'blnCase
End Function 'blnStrCompV2
Dim x, intStart, intStop, y, z
z = 300000
intStart = Timer
For x = 1 to z
blnStrComp "hello", "Hello", True
blnStrComp "Hello", "Hello", True
blnStrComp "hello", "Hello", False
blnStrComp "hello", "Hello", Empty
blnStrComp vbNull, "Hello", Null
blnStrComp Empty, Empty, "hello"
Next 'x
intStop = Timer
Wscript.echo intStop - intStart
intStart = Timer
For x = 1 to z
blnStrCompV2 "hello", "Hello", True
blnStrCompV2 "Hello", "Hello", True
blnStrCompV2 "hello", "Hello", False
blnStrCompV2 "hello", "Hello", Empty
blnStrCompV2 vbNull, "Hello", Null
blnStrCompV2 Empty, Empty, "hello"
Next 'x
intStop = Timer
Wscript.echo intStop - intStart
Article ID: 19, Created On: 9/16/2011, Modified: 9/16/2011