lispリーダーはシンボルをインターンするので、特定のシンボルへの独立した参照によってまったく同じlispオブジェクトが得られ、結果としてそれらを比較できますeq
(オブジェクトアドレスを比較するだけでよい)。
逆に、独立した文字列は常に異なるlispオブジェクトであるため、その内容を比較する必要があります。
したがってeq
、パフォーマンスで勝つ比較が期待されます。
不思議なことに十分(私は確かに非常に驚いています)、いくつかの些細なテストbenchmark-run
はstring=
かなりのマージンで勝利を与えています。これは私には非常に奇妙に思えます。YMMV?
編集:それで、私はこの答え(およびそのコメント)に再び気づき、結果を再現して説明できるかどうかを確認するために刺激を受けました。
nb最初は何もバイトコンパイルされません。
最初の認識は、私のシンボルはquote
dで、文字列はdではないことでした。そして、すぐquote
に速度の違いの大部分がにあることがわかりました。
(benchmark-run 10000000
(string= "foo" "foo"))
小さめの文字列の場合、一貫して以下より高速です。
(benchmark-run 10000000
(eq 'foo 'foo))
ただし、文字列も引用する場合:
(benchmark-run 10000000
(string= '"foo" '"foo"))
ほぼすべてが均等になります。
ただし、平均して、文字列が非常に大きい場合を除いて、文字列の比較はまだ髪に勝っているようです。
別のアプローチは、オブジェクトを変数にバインドすることです:
(let ((foo 'test)
(bar 'test))
(benchmark-run 10000000
(eq foo bar)))
(let ((foo "test")
(bar "test"))
(benchmark-run 10000000
(string= foo bar)))
もう一度言いますが、平均的には、鼻の方が文字列の比較が速くなっています。
バイトコンパイル後、let-bound変数のケースで一貫した結果のみが表示されます。この場合、(時間の約2/3)eq
より一貫して高速ですstring=
。
他の例では、引用符で囲まれた文字列が引用符で囲まれていない文字列よりも高速であるなど、無意味な(私にとっての)結果が出benchmark-run
ます。同じ関数の異なる実行の間に十分な多様性があり、異なる関数の実行間の違いを完全に覆い隠しました。
私の結論は:
(a)シンボルが引用符で囲まれている場合、シンボルとの比較は、文字列の比較よりもeq
(多少直感的には)遅くなる可能性があります。
(b)文字列がかなり大きくない限り、実際的な違いはまったく無視できるため、純粋にパフォーマンス上の理由で、一方をもう一方に変換することはありません。
eq
シンボルと比較するために使用します。