.Net全般: 2007年7月アーカイブ

TKFP.DLLの不具合を調べていたら恐ろしい事実に気付いてしまいました。.NET FrameworkのIndexOf関数がカルチャに影響されるらしい。具体的には
"xxドラエモン".IndexOf("ト゛ラ")
の結果が「-1」では無く「2」なってしまいます。
今回、不具合が発生したのは
"/ー".IndexOf("//")
が「-1」にならなかったことです。
.NET 2.0 ではまだIndexOfに比較オプションが指定できるので比較的簡単に回避できたのですが、.NET 1.1ではそれが使えずに
System.Globalization.CultureInfo.CurrentCulture.CompareInfo.IndexOf
などと言う、関数を使う羽目になりました。
今更、.NET 1.1での影響はほとんど無いのですが、TKFP.DLLでは両バージョンを同一のソースで管理しているので、おかげでコンパイルオプションだらけです。

他にも、StartsWith とか EndsWith とかも影響するようなのでちょっと見直す必要がありそうです。ContainsとかReplaceが影響しないのがさらに混乱するんですけどね。

そもそも、この仕様ってどうなんでしょう?あいまいな日本語比較より厳密な文字比較をする場面のほうが圧倒的に多いような気がするので、あいまい比較をオプションにするべきだと思うのですが。

とある作業にて大量の文字列中に特定の文字があるかどうかの検査を行う必要があり、そのときに確認した内容です。


.NET Framework 2.0 以前では文字列の存在確認で
IndexOf("あ") != -1
などという記述を大量にしていました。
最近は、
Contains("あ")
で代用することが多くなり、またこの使用法が正攻法でしょう。

通常は特にに気にしていませんでしたが、検索作業自体で数十秒かかるようになると話は別です。で、幾つかの方法を試してみることにしました。コード自体が読みにくくなる改変は避けたいので、候補は以下の3つで

(1).IndexOf("あ") != -1
(2).Contains("あ")
(3).IndexOf('あ') != -1

処理速度は (3)、(2),(1)の順で、(3)は(1)の十倍程度早くなりますね。最も、(3)は使用できる場合が限定されますが、(1)からの改変でほとんど見た目が変わらないのはいい感じです。(2)は内部では(1)を読み出していると思っていたので、最も遅いと思われましたが、検査条件を限定することで早くしていうるようで、これだけでも数倍の処理速度の差が発生します。

対象が文字列なので、すべて期待している結果が出るとは限りませんが、(1)の表記
IndexOf("あ") != -1
は、今後登場する機会はなくなりそうですね。


以上を踏まえると、大量の文章から該当するデータを探す、たとえば過去のメールデータからある文字が存在するメールを検索するようなことをする場合は、一旦、検査する先頭文字で「IndexOf('あ') != -1」と仮検査し、該当するものだけを本検査にまわす方法もありかと

2009年11月

1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30