Hi!
So, jetzt hab ich es auch noch mal ausprobiert ...
Option Explicit
Private Declare Function GetTickCount Lib "kernel32" () As Long
Public Function vInArgList(ByVal vValue As Variant, _
ParamArray vArg() As Variant) As Boolean
Dim i As Integer
Dim bFound As Boolean
bFound = False
For i = 0 To UBound(vArg)
If vValue = vArg(i) Then
bFound = True: Exit For
End If
Next i
vInArgList = bFound
End Function
Public Function vInArgListLng(ByVal vValue As Long, ByRef vArg() As Long) As _
Boolean
Dim i As Integer
For i = 0 To UBound(vArg)
If vValue = vArg(i) Then
vInArgListLng = True
Exit For
End If
Next i
End Function
Private Sub Form_Load()
Dim i As Long
Dim tmpN As Long
Dim Start As Long
Dim EndTime As Long
Dim SearchString As String
Dim arglist(0 To 5) As Long
arglist(0) = 200000
arglist(1) = 300000
arglist(2) = 400000
arglist(3) = 500000
arglist(4) = 600000
arglist(5) = 700000
SearchString = "200000 300000 400000 500000 600000 700000"
Start = GetTickCount()
For tmpN = 100000 To 999999
If tmpN = 200000 Or tmpN = 300000 Or tmpN = 400000 Or tmpN = 500000 Or _
tmpN = 600000 Or tmpN = 700000 Then
'If vInArgList(tmpN, 200000, 300000, 400000, 500000, 600000, 700000)
' Then
'If vInArgListLng(tmpN, arglist) Then
'If InStr(1, SearchString, CStr(tmpN), vbBinaryCompare) > 0 Then
i = i + 1
End If
Next tmpN
EndTime = GetTickCount()
MsgBox EndTime - Start
End Sub Wenn man nun die auskommentierten Ifs der Reihe nach ausprobiert, stellt man folgendes fest:
die Lösung mit den vielen Or ist die schnellste --> wie erwartet
vInArgList ist richtig lahm (vermutlich wegen der Variant-Datentypen)
vInArgListLng ist deutlich besser aber trotzdem schlechter als die InStr Lösung
Woran das genau liegt kann ich nicht sagen. Da ich von meinen "theoretischen" Überlegungen überzeugt bin, habe ich es nochmal mit C++ ausprobiert :
#include <windows.h>
#include <iostream>
template<class T> bool vInArgList(T value, T *vArg, size_t vArgSize)
{
for(size_t tmpN=0; tmpN<vArgSize; tmpN++)
{
if(tmpN == vArg[tmpN])
{
return true;
}
}
return false;
}
void main(void)
{
DWORD Start;
DWORD End;
size_t vArg[6];
size_t i = 0;
char *szSearchStr = "200000 300000 400000 500000 600000 700000";
char szBuffer[10];
vArg[0] = 200000;
vArg[1] = 300000;
vArg[2] = 400000;
vArg[3] = 500000;
vArg[4] = 600000;
vArg[5] = 700000;
Start = GetTickCount();
for(size_t tmpN=100000;tmpN<999999;tmpN++)
{
if((tmpN == 200000) || (tmpN == 300000) || (tmpN == 400000) || (tmpN == _
500000) || (tmpN == 600000) || (tmpN == 700000))
//if(vInArgList<size_t>(tmpN, vArg, sizeof(vArg)))
//if(strstr(szSearchStr, itoa(tmpN, szBuffer, 10)))
{
i++;
}
}
End = GetTickCount();
std::cout << End - Start << "\n";
} Und hier verhalten sich die verschiedenen Varianten wie vorhergesagt .
Bei der Gelegenheit ist mir allerdings eine Kleinigkeit aufgefallen:
Dim i As Long
Dim tmpN As Long
Dim SearchString As String
SearchString = "200000 300000 400000 500000 600000 700000"
For tmpN = 0 To 999999
If tmpN = 200000 Or tmpN = 300000 Or tmpN = 400000 Or tmpN = 500000 Or tmpN _
= 600000 Or tmpN = 700000 Then
'If InStr(1, SearchString, CStr(tmpN), vbBinaryCompare) > 0 Then
i = i + 1
End If
Next tmpN Verwendet man die InStr-Methode ist i = 37 statt wie erwartet i = 6, da eben 0, 2, 20, 200 etc. ebenfalls in dem String enthalten sind.
ciao |