-1

パーサーを作成していて、Scanner::NextToken (たとえば) によって返された現在のトークンが小さな値のセット (たとえば、5 ~ 10 個のアイテム; 数個または数個) の 1 つであるかどうかを確認する必要があるとします。

この小さなオープン ソース プロジェクト (https://github.com/gsscoder/exprengine) では、Parser クラス内で、Array::Contains() でクエリを実行するさまざまな静的配列を宣言しました (Parser::Ensure() メソッドを参照)。 )。

チェックトークンのスキャナーで使用されているのと同じ手法を使用してパフォーマンスを向上できるかどうかを推測しています。これは、if ステートメントを使用するヘルパーメソッドです (次のように)。

private static bool IsLineTerminator(int c)
{
  return c == 0x0A || c == 0x0D || c == 0x2028 || c == 0x2029;
}

それとも、スキャナーでも、パーサーで使用されている手法を使用する必要がありますか?

任意の意見 (やる気のあるもの) を歓迎します。ANTLR などのツールを使用してパーサー/スキャナーを生成することを提案しないでください。手書きの実装を維持したいと考えています。

よろしく、 ジャコモ

4

1 に答える 1

4

本質的にはまさにそれArray.Containsがやっていることです。を使用すると、その程度までインライン化されないため、コール スタックが少し複雑にContainsなりますが、何が起こっているかの基本的な考え方は同じです。劇的なパフォーマンスの違いが見られる可能性は低いですが、必ず 2 つの方法をプロファイリングして、自分の目で確かめてください。 どちらの方法がより速いかを知る最善の方法は、ランダムな見知らぬ人に尋ねるのではなく、試してみることです。

より高速になる可能性がある実際のアルゴリズムの変更を検討する別のオプションはHashSet、配列ではなく a を使用することです。値が 4 つだけの場合、速度の差は小さいと思われますが、ハッシュベースのデータ構造は、検索を大幅に高速化するように特別に設計されています。(少なくともそれもテストする価値があります)。switchステートメントもハッシュベースのソリューションとして実装されるため、それを使用することも検討できます。

于 2013-01-04T17:24:19.700 に答える