2016-03-23 16 views
42

平方よりも高速である理由:キューブは、私がこれを書いた

var max = 0xffffff * 4; 
    var step = 1/max; 
    function cube() { 
    var result = 0.; 
    for (var x = 0.; x < 1; x += step) { 
     result += x * x * x; 
    } 
    return result; 
    } 
    function mul() { 
    var result = 0.; 
    for (var x = 0.; x < 1; x += step) { 
     result += x * x; 
    } 
    return result; 
    } 
    function go() { 
    var r = ''; 
    r += cube() + ' \n'; 
    r += mul() + ' \n'; 
    alert(r); 
    } 

とChromeプロファイラでの結果を参照してください。

mul: 106ms 
cube: 87ms 

どうということは可能ですか?

+0

これをjsfiddleに投げかけてみると、 'mul'は'キューブ 'より10〜20%遅くなっています。面白い。 –

+7

'go()'の中で呼び出しの順番を入れ替えると高速になりますか? – dlatikay

+0

@dlatikay私はそれを試みたが、それは違いを生じさせるように見えなかった。 –

答えて

-5

一部のブラウザでは、JITがバックグラウンドでコンパイルする間にJavaScriptが解釈されるようになっています。 JavaScriptがコンパイルされると、より速く実行されます。

+0

WebブラウザはJSコードをコンパイルして実行することはできませんが、これは巨大なセキュリティホールを追加します。 – Cristik

+4

@Cristikあなたはアサーションをダブルチェックしてください;-) –

+0

@DidierLあなたのコメントをもっと詳しく教えてください。私は間違っているかもしれませんが、理由を知ることは良いでしょう:) – Cristik

33

あなたのアサーションは間違っています。キューブはmulより高速ではなく、あなたの例はそれを証明しません。

実際、Javascriptの実行の内部は実際の乗算よりも時間がかかり、結果としてmulとcubeの時間は非常に似ています。ループ内で2つの関数を実行しただけで違いを増やすことができ、プロファイラでは20219 vs 20197が重要ではありません。そしてBTW、キューブはここでは「より遅い」ものです。

さらに、ループ内で数学を行う前にChromeとFirefoxの両方が最適化されているため、このプロファイリングの方法は機能しません。ループとは、最適化が同じ結果を返すことを知っているキャッシュされた値または数学的関数をループで使用する可能性があります。また

<script> 
var max = 0xffffff * 4; 
    var step = 1/max; 
    function cube() { 
    var result = 0.; 
    for (var x = 0.; x < 1; x += step) { 
     result += x * x * x; 
    } 
    return result; 
    } 
    function mul() { 
    var result = 0.; 
    for (var x = 0.; x < 1; x += step) { 
     result += x * x; 
    } 
    return result; 
    } 
    function go() { 
    var s=''; 
    for (var i=0; i<100; i++) { 
     s+=cube(); 
     s+=mul(); 
    } 
    console.log(s); 
    } 
    go(); 
</script> 

参照のみが、ここではビデオを見て、::

ここで私が使用したコードは、Firefoxの男は説明https://fosdem.org/2016/schedule/event/mozilla_benchmarking_javascript_tips/をmicrobenchmarkingは本当に多くの意味ではない理由。

+0

Chrome 49では、私が見ているところではそうではありません。 'mul'は'キューブ 'よりも一貫して遅いです。さまざまなブラウザで異なる結果 - これはChromeが作成している特定の最適化に関するものです - Qの下のコメントチェーンを参照してください。プロファイリングループの構築方法を表示できますか? EGそれは純粋に数学に基づいた関数なので、戻り値を使用しない場合は、計算全体を最適化するかもしれません。 –

+0

[the jsperf test](http://jsperf.com/test-math-differenced)クロム48は両方とも同じですが、49と50は「マルチ」よりも「キューブ」の方が毎秒多くの操作を示しています。 –

+0

終了値を使用するか使用しないかは、Chrome 49.0.2623.87 mを使用して100回ループします。キューブは一貫していますが、mulよりも大幅に遅くはありません。 –

0

これは、すべての数値が1未満であるため、キューブ関数が正方形よりも小さい数値を追加しているためです(実際にどのように動作するかはわかりません)。これは単なる推測です。数が非常に小さいので、これは不適切な精度によるものでもあります。また、私はキューブが1つを超える数字でテストしました。

+2

あなたの推測は間違っています。数字の "サイズ"はまったく問題ではなく、 "サイズ"に関係なく常に数字でいっぱいです。ほとんどの操作は仮数で実行されます。 – shal

0

オプティマイザは、それらのうちの1つをベクトル命令で実行できると判断し、もう1つは単純な古いfmulを使用すると判断することがあります。私は「正方形」はfmulを使用し、キューブはベクトル命令mulpdを使用すると推測しています。これは、1つの命令で最大4倍を乗算することができます。私は4倍にした 'クワッド'を追加し、その時間はキューブにかなり近づいています。しかし、私が「5」に行ったとき、それは正方形より遅くなりました。これは、ベクトル命令がキューブとクワッドに使用されているという間接的な証拠です。

タブレットのインテルcpu vsアームの結果を見ると面白いでしょう。

関連する問題