Dictionary can't handle Longs > 10,000,000?

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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top