R
R Avery
I was writing a program that took surprisingly long. I started
commenting things out to figure out what was taking so long, and the
very last thing i checked - the very last thing i would have thought
would take so long - was it. The dictionary object. I was using keys
of type Long like 19980512, and it was taking forever. So, I did a test
to see why. I could have sworn longs were always an OK choice for keys
in the past. I played around with it until i came to the magic number
of 10,000,000. Any Long above this number takes 220 times longer to add
to the dictionary than a Long below.
Does anyone have any idea why? Poor hashing function? Bug?
Sub DictionaryTesting()
Dim i As Long, dic As New Scripting.Dictionary
Dim myTimer As New clsTimer
myTimer.StartTimer
For i = 1 To 10000
dic.Add i + 10000001#, i - 1
Next i
myTimer.StopTimer
Debug.Print "Long, > 10,000,000", myTimer.PerformanceString
Set dic = Nothing
myTimer.StartTimer
For i = 1 To 10000
dic.Add i + 9989999#, i - 1
Next i
myTimer.StopTimer
Debug.Print "Long, < 10,000,000", myTimer.PerformanceString
Set dic = Nothing
myTimer.StartTimer
For i = 1 To 10000
dic.Add CDbl(i + 9990999#), i - 1
Next i
myTimer.StopTimer
Debug.Print "Double", myTimer.PerformanceString
Set dic = Nothing
myTimer.StartTimer
For i = 1 To 10000
dic.Add CVar(i + 9990999#), i - 1
Next i
myTimer.StopTimer
Debug.Print "Variant", myTimer.PerformanceString
Set dic = Nothing
myTimer.StartTimer
For i = 1 To 10000
dic.Add CSng(i + 9990999#), i - 1
Next i
myTimer.StopTimer
Debug.Print "Single", myTimer.PerformanceString
Set dic = Nothing
myTimer.StartTimer
For i = 1 To 10000
dic.Add CStr(i + 19990101), i - 1
Next i
myTimer.StopTimer
Debug.Print "String", myTimer.PerformanceString
End Sub
--------------------------------------
clsTimer
--------------------------------------
'Private Declare Function timeBeginPeriod Lib "winmm.dll" (ByVal uPeriod
As Long) As Long
'Private Declare Function timeEndPeriod Lib "winmm.dll" (ByVal uPeriod
As Long) As Long
Private Declare Function timeGetTime Lib "winmm.dll" () As Long
' Properties.
Private m_lngBeginTime As Long
Private m_lngEndTime As Long
Private m_blnRunning As Boolean
'##########################################################################
' Read properties.
'##########################################################################
Public Property Get BeginTime() As Long
BeginTime = m_lngBeginTime
End Property
Public Property Get EndTime() As Long
EndTime = m_lngEndTime
End Property
Public Property Get Running() As Boolean
Running = m_blnRunning
End Property
'##########################################################################
' Write properties.
'##########################################################################
'##########################################################################
' Methods.
'##########################################################################
Public Sub StartTimer()
m_blnRunning = True
m_lngBeginTime = timeGetTime()
End Sub
Public Sub StopTimer()
m_lngEndTime = timeGetTime()
m_blnRunning = False
End Sub
Public Function PerformanceString() As String
PerformanceString = SecondsElapsed() & " seconds elapsed."
End Function
Public Function TimeElapsed() As Long
If m_blnRunning Then
TimeElapsed = timeGetTime() - m_lngBeginTime
Else
TimeElapsed = m_lngEndTime - m_lngBeginTime
End If
End Function
Public Function SecondsElapsed() As Double
If m_blnRunning Then
SecondsElapsed = (timeGetTime() - m_lngBeginTime) / 1000
Else
SecondsElapsed = (m_lngEndTime - m_lngBeginTime) / 1000
End If
End Function
commenting things out to figure out what was taking so long, and the
very last thing i checked - the very last thing i would have thought
would take so long - was it. The dictionary object. I was using keys
of type Long like 19980512, and it was taking forever. So, I did a test
to see why. I could have sworn longs were always an OK choice for keys
in the past. I played around with it until i came to the magic number
of 10,000,000. Any Long above this number takes 220 times longer to add
to the dictionary than a Long below.
Does anyone have any idea why? Poor hashing function? Bug?
Sub DictionaryTesting()
Dim i As Long, dic As New Scripting.Dictionary
Dim myTimer As New clsTimer
myTimer.StartTimer
For i = 1 To 10000
dic.Add i + 10000001#, i - 1
Next i
myTimer.StopTimer
Debug.Print "Long, > 10,000,000", myTimer.PerformanceString
Set dic = Nothing
myTimer.StartTimer
For i = 1 To 10000
dic.Add i + 9989999#, i - 1
Next i
myTimer.StopTimer
Debug.Print "Long, < 10,000,000", myTimer.PerformanceString
Set dic = Nothing
myTimer.StartTimer
For i = 1 To 10000
dic.Add CDbl(i + 9990999#), i - 1
Next i
myTimer.StopTimer
Debug.Print "Double", myTimer.PerformanceString
Set dic = Nothing
myTimer.StartTimer
For i = 1 To 10000
dic.Add CVar(i + 9990999#), i - 1
Next i
myTimer.StopTimer
Debug.Print "Variant", myTimer.PerformanceString
Set dic = Nothing
myTimer.StartTimer
For i = 1 To 10000
dic.Add CSng(i + 9990999#), i - 1
Next i
myTimer.StopTimer
Debug.Print "Single", myTimer.PerformanceString
Set dic = Nothing
myTimer.StartTimer
For i = 1 To 10000
dic.Add CStr(i + 19990101), i - 1
Next i
myTimer.StopTimer
Debug.Print "String", myTimer.PerformanceString
End Sub
--------------------------------------
clsTimer
--------------------------------------
'Private Declare Function timeBeginPeriod Lib "winmm.dll" (ByVal uPeriod
As Long) As Long
'Private Declare Function timeEndPeriod Lib "winmm.dll" (ByVal uPeriod
As Long) As Long
Private Declare Function timeGetTime Lib "winmm.dll" () As Long
' Properties.
Private m_lngBeginTime As Long
Private m_lngEndTime As Long
Private m_blnRunning As Boolean
'##########################################################################
' Read properties.
'##########################################################################
Public Property Get BeginTime() As Long
BeginTime = m_lngBeginTime
End Property
Public Property Get EndTime() As Long
EndTime = m_lngEndTime
End Property
Public Property Get Running() As Boolean
Running = m_blnRunning
End Property
'##########################################################################
' Write properties.
'##########################################################################
'##########################################################################
' Methods.
'##########################################################################
Public Sub StartTimer()
m_blnRunning = True
m_lngBeginTime = timeGetTime()
End Sub
Public Sub StopTimer()
m_lngEndTime = timeGetTime()
m_blnRunning = False
End Sub
Public Function PerformanceString() As String
PerformanceString = SecondsElapsed() & " seconds elapsed."
End Function
Public Function TimeElapsed() As Long
If m_blnRunning Then
TimeElapsed = timeGetTime() - m_lngBeginTime
Else
TimeElapsed = m_lngEndTime - m_lngBeginTime
End If
End Function
Public Function SecondsElapsed() As Double
If m_blnRunning Then
SecondsElapsed = (timeGetTime() - m_lngBeginTime) / 1000
Else
SecondsElapsed = (m_lngEndTime - m_lngBeginTime) / 1000
End If
End Function