1 2 3
のような文字列があり、double
を含む部分文字列の位置を特定すると、一時文字列を作成せずに部分文字列から直接解析する方法はありますか?直接重複する部分文字列を解析する
たとえば、私はSystem.Double.Parse(str.Substring(0, 1))
を実行できますが、それはゆっくりと不要な一時的な文字列を作成します。元の文字列の一部から直接doubleを解析することは可能ですか?
EDIT
エリックリペットは「小さな文字列が安い」と述べて、ここに私の動機に疑問を呈しました。この動機は、intの構文解析で同じことをして、小さな文字列がそれほど安くないため、大幅なパフォーマンスの向上が見られるからです。ここで
は、一時的な文字列を使用してintのシーケンスをlexes機能である:
let lex f (s: string) =
let rec inside i0 (s: string, i) =
if i = s.Length then
f (s.Substring(i0, i-i0) |> System.Int32.Parse)
else
let c = s.[i]
if '0'<=c && c<='9' then
inside i0 (s, i+1)
else
f (s.Substring(i0, i-i0) |> System.Int32.Parse)
outside (s, i)
and outside (s: string, i) =
if i < s.Length then
let c = s.[i]
if '0'<=c && c<='9' then
inside i (s, i)
else
outside (s, i+1)
outside (s, 0)
これは、文字列から15625000個のint型をlexのために2.4sかかります。
let lex f (s: string) =
let rec inside n (s: string, i) =
if i = s.Length then f n else
let c = s.[i]
if '0'<=c && c<='9' then
inside (10*n + int c - int '0') (s, i+1)
else
f n
outside (s, i)
and outside (s: string, i) =
if i < s.Length then
let c = s.[i]
if '0'<=c && c<='9' then
inside 0 (s, i)
else
outside (s, i+1)
outside (s, 0)
は、この一時的な文字列を使用するソリューションよりも速く9xの上、0.255sをとります。
はここで一時的な文字列を回避したバージョンです!
なぜ字句浮動小数点数が異なるべきなのかわかりません。したがって、部分文字列から浮動小数点数を解析する機能を提供しないことによって、.NET上ではテーブルのパフォーマンスが一桁も離れた状態になります。私は多くの科学的コンピューティングを行い、多くの場合、特にスタートアップ時に大量のデータをレックスする必要があるため、このような風にパフォーマンスを投げたくはありません。
極端なマイクロ最適化のようです。ライブラリが必要になるか、本格的なダブルパーサーを書くことになりますが、これはまさに単純な作業ではありません。 – Rob
実際にここで特定されたパフォーマンスの問題がありますか?小さな弦は安いです。つまり、個々の文字だけをコピーするレクサーを書くことができます。 –
@EricLippert:一時ファイルを作成せずにintを解析するためのベンチマークコードで質問を更新しました.9倍以上高速です。私は、浮動小数点の解析でも同様に巨大なパフォーマンスの向上が見られると考えています。つまり、「小さな文字列は安い」とは言いません。 –