2016-11-18 5 views
1

でバイトを反復私は非常に単純なハッシュ関数を必要とし、Excelでいくつかの実験に基づくバイト値のちょうど合計がそれを行う必要があります。スピードアップのMS Access VBAスクリプトがString

Function HashPart(strVal As String) As Long 
    ' work with byte representation for speed 
    Dim b() As Byte 
    b = strVal 

    Dim result As Long 
    result = 0 
    For i = 0 To UBound(b) 
     result = result + b(i) 
    Next 
    Quersumme = result 
End Function 

これは、多くのをやっていますクエリーに起因するすべてのレコード(約100)の時間:

Set rs = db.OpenRecordset(strSQL) 

' Loop through records 
Do While Not rs.EOF 
    resultHash = resultHash + HashPart(rs(0)) 
    resultLen = resultLen + Len(rs(0)) 
    rs.MoveNext 
Loop 
rs.Close 
MyHash = Str(resultLen) & "-" & Str(resultHash) 

これは十分に機能しますが、非常に遅いです。私の以前のバージョンでは、Midを使ってStringを繰り返し処理していましたが、これはさらに遅くなりましたが、現在は改善する方法がありません。

これをスピードアップする方法はありますか?


編集:問題はハッシュ関数ではなく、クエリにありました。

+0

「HashPart =」を定量化する場所がわかりません。 – user3819867

+0

@ user3819867修正済み、ありがとう! – Beginner

+1

あなたの弦はどれくらいの長さですか(平均して)、どのくらい遅いですか? 110文字でこの文字列を10,000回実行すると、0.04秒かかります。だからおそらくあなたのクエリは遅く、関数ではありません。 – Andre

答えて

3

定数文字列のテストコードは、関数自体が非常に高速であることを示しました。 ca.の文字列で10,000コール110文字は0.04秒しかかかりません。

結論:パフォーマンス上の問題は、ハッシュ関数ではなく、クエリにありました。

Function HashPart(strVal As String) As Long 

    ' work with byte representation for speed 
    Dim b() As Byte 
    Dim result As Long 
    Dim i As Long 

    b = strVal 
    result = 0 

    For i = 0 To UBound(b) 
     result = result + b(i) 
    Next 

    HashPart = result 

End Function 

Sub TestHashPart() 

    Const NumRounds = 10000 

    Dim i As Long 
    Dim res As Long 
    Dim SumRes As Double ' avoid limitation of Long (2^31) 
    Dim S As String 
    Dim t1 As Single 

    t1 = Timer 
    For i = 1 To NumRounds 
     ' constant string with tiny variations 
     S = "abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ " & CStr(i^2) 
     res = HashPart(S) 
     ' This would slow down the process dramatically. DO NOT activate for NumRounds > 1000 ! 
     ' Debug.Print i, res, Len(S), S 
     SumRes = SumRes + res 
    Next i 

    Debug.Print SumRes, Timer - t1 & " seconds" 

End Sub 
+0

ありがとう!正しい方向に検索した後、私は物事をスピードアップする方法を見つけました。 – Beginner

1
Function HashPart(strVal As String) As Long 
    ' work with byte representation for speed 
    Dim b() As Byte 
    b = strVal 
    For i = 0 To UBound(b) 
     HashPart = HashPart + b(i) 
    Next 
End Function 

改善することはあまりありません、私はあなたがそこに追加の変数を入れていないと0にデフォルトはあなたが非常にわずかほうだと0に番号を設定しない場合を考えます。