2017-08-23 12 views
-1

こんにちは誰もJavaの数学演算子の相対的なパフォーマンス/コストに関する参照はありますか?数学演算子のJavaの相対的な性能

理想的には、コードのようなものコンプリート2(私は今手元に持っていない)、それは次のようになります

  • 追加:1つの
  • 減算:2
  • 乗算:10
  • 分割:100
  • 対数:600
  • 指数:500の

感謝。

+2

あなたの質問についてもっと明白なことができますか?これらの数字は何を意味しますか?それは "*部門は追加*よりも約100倍遅い"という意味ですか?あなたが私に尋ねるならば、プラットフォームは非常に依存しています。あなたの正確なコードがどのように見えるか、** JVM **の最適化の数、結果のマシンコードの見た目と正確なプロセッサーの実行方法に大きく依存します。意味のあるベンチマークを作成することは間違いありません。 – Zabuza

+0

たとえば、いくつかの頻繁な乗算や他のタスク(それらは単に計算され、テーブルに格納されている)には多くのプロセッサが**ルックアップテーブル**を使用するため、即座に応答を返すことができます。このフィールドは、ベンチマークではほとんど制御できないような極めて高度な最適化です。 – Zabuza

+0

例として、 'int sum = 0; for(int i = 0; i <100; i ++){sum ++; } '、** JVM **はこれをバイトコード(* .class *ファイル)の単一の文' int sum = 100; 'に変換します。それは、追加が非常に高速になるように見えます。そのような誤った仮説を実行するのはとても簡単です。 – Zabuza

答えて

0

私は一緒にこの急ごしらえのホイップ、非公式、完全に非科学的なテストコード:私の環境では

import java.util.function.BinaryOperator; 

public class Test { 
    private static void test(String desc, BinaryOperator<Double> op, double a, double b, long startIter) 
    { 
     long maxIter = startIter; 
     long elapsed; 
     do { 
      maxIter *= 2; 
      long start = System.currentTimeMillis(); 
      for (long niter = 0; niter < maxIter; ++niter) { 
       double res = op.apply(a, b); 
      } 
      elapsed = System.currentTimeMillis() - start; 
     } while (elapsed <= 10_000); 
     System.out.printf("%-15s/sec\t%g\n", 
      desc, (maxIter * 1000.0)/elapsed); 
    } 

    public static void main(String[] arg) 
    { 
     test("Addition (double)", (Double a, Double b) -> { 
      return a + b; 
     }, 483902.7743, 42347.775, 10_000_000); 
     test("Subtraction (double)", (Double a, Double b) -> { 
      return a - b; 
     }, 483902.7743, 42347.775, 10_000_000); 
     test("Multiplication (double)", (Double a, Double b) -> { 
      return a * b; 
     }, 483902.7743, 42347.775, 1_000_000); 
     test("Division (double)", (Double a, Double b) -> { 
      return a/b; 
     }, 483902.7743, 42347.775, 1_000_000); 
     test("Log10", (Double a, Double b) -> { 
      return Math.log10(a); 
     }, 483902.7743, 42347.775, 1_000_000); 
     test("LogE", (Double a, Double b) -> { 
      return Math.log(a); 
     }, 483902.7743, 42347.775, 1_000_000); 
     test("Power", (Double a, Double b) -> { 
      return Math.pow(a, b); 
     }, 483902.7743, 12, 100_000); 
    } 
} 

---標準のJava 8 JDK、インテルCore2のクワッドQ8300する@ 2.5GHz帯---からの代表生の出力このテストは次のとおりです。

我々が持っている相対的なパフォーマンスへの変換
Addition (double)/sec 6.18619e+08 
Subtraction (double)/sec 4.10651e+08 
Multiplication (double)/sec 3.27010e+07 
Division (double)/sec 3.22215e+07 
Log10   /sec 1.99330e+07 
LogE   /sec 1.99206e+07 
Power   /sec 8.67870e+06 

Addition   1.0 
Subtraction  1.5 
Multiplication 18.9 
Division   19.2 
Log10   31.0 
LogE    31.1 
Power   71.3 

いつものように、あなたの走行距離は変わるかもしれません。

+0

ありがとう、これは多かれ少なかれ私が探していたものです!一つのことは、私は常にこれらと一緒に疑問に思うので、私はいつも同じ番号(キャッシュ)でコンパイラの最適化について心配しているので、各繰り返しで数値を得るためにランダムを使う方が良いかどうかです。例えば、ルックアップテーブル(Zabuzaが言ったことへのコールバック)のために、ログを取るのは本当に簡単です。 –

+0

はい、おそらく、さまざまな異なる引数を使用するより現実的な画像を与えるでしょう。私は全体的なランクに劇的な変化はないと思いますが、相対的なパフォーマンスの見積もりは単なるものです。たとえば、乗算は18よりもむしろ「実際に」19または14の加算であることがわかりますが、3回または4回の加算ではなく、ログは「実際に」28または34の加算であるかもしれませんが、乗算よりも... –

+0

-1「乗法、減法、加算」の順序で試してみてください。 Googleは、バイ・メガモードのコールサイトが理解できるようにしています。それを正しく行うにはJMHを使用してください。 – maaartinus