JavaScriptで文字列を数値に変換する最も速い方法は何ですか?


122

任意の数、それは数です。文字列は数字のように見えます、それは数字です。それ以外はすべてNaNになります。

'a' => NaN
'1' => 1
1 => 1

最も速いのは、特定の時間における特定の実装の最適化に依存します。客観的に「最速」の方法はありません。
レイジーを憎む

2
'1a'文字列で何をすべきですか?' 1'1?言い換えれば、なぜそれを行うための最も一般的な方法(Number(x)およびparseInt(x, 10))では不十分なのですか?
raina77ow


ここで、さまざまなメソッドの優れたパフォーマンス比較:jsben.ch
#

回答:


191

私の知る限り、4つの方法があります。

Number(x);
parseInt(x, 10);
parseFloat(x);
+x;

私が作成したこの簡単なテストでは、実際にはブラウザーに依存しています。

http://jsperf.com/best-of-string-to-number-conversion/2

Implicit は3つのブラウザーで最速とマークされていますが、コードが読みにくくなっています...だから、好きなように選んでください!


7
興味深いことに、Google Analytics(Webサイトに貼り付ける部分)は1*、日付から数値への変換に使用します+。これは、上記と同様です。つまり、と1*new Date()いうより+new Date()。おそらくそれはもっと読みやすいですか?
Matthew Wilcoxson 2013年

1
1*エラーが発生しにくいため、好ましいと思います。以前の不要なダングリング変数+1は解析エラーではありません。これは、での使用if (MYCONSTANT == myvar)に似たトリックCです。
トーマス

5
@beatak-現在の最適化は、暗黙的な変換ではなく、ネイティブメソッドを優先するようです。私はWindows Server 2008 R2 / 7上のChrome 37.0.2062.124のNumber()とFirefox 30.0のParseInt()で最も速くなり、暗黙的に両方で最も遅くなっています。また、一般的な比較のために、テストに文字列リテラルfloatを含めることを検討することもできます。文字列から浮動小数点への変換は一般に文字列から整数への変換よりも遅いため、場合によっては順序が変わる可能性があると私は推測しています。現在のテストの方法では、Number()を使用すると、文字列から整数への変換がなくなります。
Nolo

1
Chrome 61.0.3163。Number()が最も高速です。
Dmitry Petukhov 2017年

70

これには少なくとも5つの方法があります。

整数のみに変換したい場合、もう1つの高速(および短い)方法は、2ビットではない(つまり、2つのチルド文字を使用する)方法です。

例えば

~~x;

リファレンス:http : //james.padolsey.com/cool-stuff/double-bitwise-not/

これまでにわかっている、文字列を数値に変換する5つの一般的な方法には、すべて異なる点があります(機能するビット単位の演算子は他にもありますが、すべて同じ結果になります~~)。このJSFiddleは、デバッグコンソールに期待することができます異なる結果を示していますhttp://jsfiddle.net/TrueBlueAussie/j7x0q0e3/22/

var values = ["123",
          undefined,
          "not a number",
          "123.45",
          "1234 error",
          "2147483648",
          "4999999999"
          ];

for (var i = 0; i < values.length; i++){
    var x = values[i];

    console.log(x);
    console.log(" Number(x) = " + Number(x));
    console.log(" parseInt(x, 10) = " + parseInt(x, 10));
    console.log(" parseFloat(x) = " + parseFloat(x));
    console.log(" +x = " + +x);
    console.log(" ~~x = " + ~~x);
}

デバッグコンソール:

123
  Number(x) = 123
  parseInt(x, 10) = 123
  parseFloat(x) = 123
  +x = 123
  ~~x = 123
undefined
  Number(x) = NaN
  parseInt(x, 10) = NaN
  parseFloat(x) = NaN
  +x = NaN
  ~~x = 0
null
  Number(x) = 0
  parseInt(x, 10) = NaN
  parseFloat(x) = NaN
  +x = 0
  ~~x = 0
"not a number"
  Number(x) = NaN
  parseInt(x, 10) = NaN
  parseFloat(x) = NaN
  +x = NaN
  ~~x = 0
123.45
  Number(x) = 123.45
  parseInt(x, 10) = 123
  parseFloat(x) = 123.45
  +x = 123.45
  ~~x = 123
1234 error
  Number(x) = NaN
  parseInt(x, 10) = 1234
  parseFloat(x) = 1234
  +x = NaN
  ~~x = 0
2147483648
  Number(x) = 2147483648
  parseInt(x, 10) = 2147483648
  parseFloat(x) = 2147483648
  +x = 2147483648
  ~~x = -2147483648
4999999999
  Number(x) = 4999999999
  parseInt(x, 10) = 4999999999
  parseFloat(x) = 4999999999
  +x = 4999999999
  ~~x = 705032703

~~xバージョン他の人が、多くの場合につながる「より」の場合、内数で結果undefinedが、それは(それが返されます例えば、無効な入力のために失敗し0た文字列が非数値文字が含まれている場合、後に有効な番号)。

オーバーフロー

注意:で整数オーバーフローまたはビット切り捨てが発生する可能性があります~~が、他の変換では発生しません。このような大きな値を入力することは珍しいことですが、これに注意する必要があります。より大きな値を含むように例を更新しました。

一部のPerfテストでは、標準parseIntparseFloat関数が実際には最速のオプションであり、おそらくブラウザーによって高度に最適化されていることが示されていますが、すべてのオプションは十分に高速であるためすべて要件に依存します:http : //jsperf.com/best-of-string-to -数値変換/ 37

これはすべて、一部のparseInt / parseFloatがはるかに遅いことを示すように、perfテストがどのように構成されているかに依存します。

私の理論は:

  • うそ
  • ダーンライン
  • 統計学
  • JSPerfの結果:)

3
2147483647より大きい数値には特に注意してください。例: ~~4294967296はを返します0
ジョセフGoh

@JosephGoh:機会があれば、結果を拡張してint範囲のオーバーフローを含めるようにします。一般的に、数値がそのように大きい場合は、非常に特別なインターフェースが使用されているため、オーバーフローに注意する必要があります。乾杯
コーディング終了

@JosephGoh:興味深いことに、Chromeでは0は得られず、符号付きの最大値を超える負の数値が得られます。次に、unsigned int max値を超えると、余分なビットを単にドロップするように見えます。例: "4999999999" => 705032703
Gone Coding

8

文字列の前に+演算子を付けます。

console.log(+'a') // NaN
console.log(+'1') // 1
console.log(+1) // 1

7

文字列を整数に変換する高速な方法は、ビットごと、または次のように使用することです。

x | 0

それは実装方法に依存しますが、理論的+xには、最初にx数値にキャストしてから非常に効率的なorを実行するため、比較的高速(少なくともと同じくらい高速)である必要があります。


はい、しかし、私はこのテクニックが大きな整数を切り捨てると信じています、それはかなり悪いです。なお、Math.floor()の代わりに使用することもできますが、同じ問題があります。
Jean

ここだ様々なビット演算子のjsperf最初の答えのメソッドと組み合わせては。一部のブラウザーは前のテストの同様のコードに基づいて次のテストを最適化することがわかったので、順序をランダム化しました。トップアンサーとは異なり、暗黙的な方法が最悪の方法であることがわかりました。
冥王星

4

これを行う簡単な方法を次に 示します。var num = Number(str); この例では、strは文字列を含む変数です。テストして、それがどのように機能するかを確認することができます:Google Chrome開発者ツール、次にコンソールに移動して次のコードを貼り付けます。コメントを読んで、変換がどのように行われるかをよく理解してください。

// Here Im creating my variable as a string
var str = "258";


// here im printing the string variable: str
console.log ( str );


// here Im using typeof , this tells me that the variable str is the type: string
console.log ("The variable str is type: " + typeof str);


// here is where the conversion happens
// Number will take the string in the parentesis and transform it to a variable num as type: number
var num = Number(str);
console.log ("The variable num is type: " + typeof num);


3

これはおそらくそれほど速くはありませんが、数値が少なくとも特定の値(例:0)、または多くても特定の値であることを確認できるという追加の利点があります。

Math.max(input, 0);

最小値を確認する必要がある場合は、通常、

var number = Number(input);
if (number < 0) number = 0;

Math.max(..., 0) 2つのステートメントを書く手間を省きます。


なぜ使用しないのMath.abs(input)ですか?また、文字列を正の数に変換し、いくつかの余分な文字を節約します。
アーロンギリオン

1
@AaronGillion:Math.max(-5、0)は0を返します。Math.abs(-5)は5を返します。これは、ユースケースによって異なります。
Dan Dascalescu 2016

1
ああ、おっと、そうです。私がそのコメントを書いた深夜の間、私のユースケースはまったく異なりました。
アーロンギリオン

input数に変換できない場合は、次のようになりますNaN
Domas Mar

0

正式にリリースされたばかりの測定およびデータ型変換ライブラリであるUnitOfをお試しください。UnitOfは非常に高速で、サイズが小さく、エラーやnull /未定義をスローすることなくあらゆるデータ型を変換するのに効率的です。定義したデフォルト値またはUnitOfのデフォルトは、変換が失敗したときに返されます。

//One liner examples
UnitOf.DataType("12.5").toFloat(); //12.5 of type Float is returned. 0 would be returned if conversion failed.
UnitOf.DataType("Not A Num").toInt(10); //10 of type Int is returned as the conversion failed.

//Or as a variable
var unit = UnitOf.DataType("12.5");
unit.toInt(5); //12.5 of type Float is returned. 5 would be returned if the conversion failed.
unit.toFloat(8); // 12 of type Int is returned. 8 would be returned if the conversion failed.

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.