おやすみなさい、
私はしばらくの間、ファジー文字列マッチングに取り組んでおり、C をいくつかのポインターと共に使用して、2 つの文字列間のレーベンシュタイン距離の非常に高速な (私のニーズに合わせた) 実装を作成できました。unsafe コードとfixed
キーワードを使用してコードを C# に移植しようとしましたが、パフォーマンスが大幅に低下しました。そこで、C++ dll をビルドして使用することにしました。[DllImport]
C# から、すべての文字列を自動的にマーシャリングします。問題は、プロファイリングの後、これが私のプログラムの中で最も時間のかかる部分であり続け、プログラムの総実行時間の 50 ~ 57% を占めていることです。約 300 万のデータベース レコードから取得したテキスト フィールドの多くの部分文字列を処理する必要があると思うので、レーベンシュタイン距離にかかる時間はほとんど許容できないと思います。ということで、以下のコードに対してアルゴリズムまたはプログラミング関連の提案があるかどうか、またはこの距離を計算するためのより良いアルゴリズムを知っているかどうかを知りたいです。
#define Inicio1 (*(BufferVar))
#define Inicio2 (*(BufferVar+1))
#define Fim1 (*(BufferVar+2))
#define Fim2 (*(BufferVar+3))
#define IndLinha (*(BufferVar+4))
#define IndCol (*(BufferVar+5))
#define CompLinha (*(BufferVar+6))
#define TamTmp (*(BufferVar+7))
int __DistanciaEdicao (char * Termo1, char * Termo2, int TamTermo1, int TamTermo2, int * BufferTab, int * BufferVar)
{
*(BufferVar) = *(BufferVar + 1) = 0;
*(BufferVar + 2) = TamTermo1 - 1;
*(BufferVar + 3) = TamTermo2 - 1;
while ((Inicio1 <= *(BufferVar + 2)) && (Inicio2 <= *(BufferVar + 3)) && *(Termo1 + Inicio1) == *(Termo2 + Inicio2))
Inicio1 = ++Inicio2;
if (Inicio2 > Fim2) return (Fim1 - Inicio1 + 1);
while ((Fim1 >= 0) && (Fim2 >= 0) && *(Termo1 + Fim1) == *(Termo2 + Fim2))
{ Fim1--; Fim2--;}
if (Inicio2 > Fim2) return (Fim1 - Inicio1 + 1);
TamTermo1 = Fim1 - Inicio1 + 1;
TamTermo2 = Fim2 - Inicio2 + 1;
CompLinha = ((TamTermo1 > TamTermo2) ? TamTermo1 : TamTermo2) + 1;
for (IndLinha = 0; IndLinha <= TamTermo2; *(BufferTab + CompLinha * IndLinha) = IndLinha++);
for (IndCol = 0; IndCol <= TamTermo1; *(BufferTab + IndCol) = IndCol++);
for (IndCol = 1; IndCol <= TamTermo1; IndCol++)
for (IndLinha = 1; IndLinha <= TamTermo2; IndLinha++)
*(BufferTab + CompLinha * IndLinha + IndCol) = ((*(Termo1 + (IndCol + Inicio1 - 1)) == *(Termo2 + (IndLinha + Inicio2 - 1))) ? *(BufferTab + CompLinha * (IndLinha - 1) + (IndCol - 1)) : ((*(BufferTab + CompLinha * (IndLinha - 1) + IndCol) < *(BufferTab + CompLinha * (IndLinha - 1) + (IndCol - 1))) ? ((*(BufferTab + CompLinha * IndLinha + (IndCol - 1)) < *(BufferTab + CompLinha * (IndLinha - 1) + IndCol)) ? *(BufferTab + CompLinha * IndLinha + (IndCol - 1)) : *(BufferTab + CompLinha * (IndLinha - 1) + IndCol)) : ((*(BufferTab + CompLinha * IndLinha + (IndCol - 1)) < *(BufferTab + CompLinha * (IndLinha - 1) + (IndCol - 1))) ? *(BufferTab + CompLinha * IndLinha + (IndCol - 1)) : *(BufferTab + CompLinha * (IndLinha - 1) + (IndCol - 1)))) + 1);
return *(BufferTab + CompLinha * TamTermo2 + TamTermo1);
}
BufferVar と BufferTab は 2 つの外部int *
(この場合、int[]
C# からマーシャリングされる変数) であり、プロセス全体を高速化するためにすべての関数呼び出しでインスタンス化しないことに注意してください。それでも、このコードは私のニーズに対してかなり遅いです。誰かが私にいくつかの提案をしてもらえますか、可能であれば、より良いコードを提供してもらえますか?
編集:距離を制限することはできません。実際の距離が必要です。
どうもありがとうございました、