• 首页
• 前端开发
• 为什么预计算sin(X)比在Java脚本中使用Math.sin()要慢？

# 为什么预计算sin(X)比在Java脚本中使用Math.sin()要慢？ [英] Why is precomputing sin(x) *slower* than using Math.sin() in Javascript?

### 问题描述

``````function MyTest()
{
var ITERATION_COUNT = 1000000;

var angle = Math.floor(Math.random() * 360);

var test1 = 200 * sinArray[angle];

var test2 = 200 * cosArray[angle];

var ref = document.getElementById("Output1");

var outData = "Test 1 : " + test1.toString().trim() + "<br><br>";
outData += "Test 2 : "+test2.toString().trim() + "<br><br>";

var time1 = new Date();     //Time at the start of the test

for (var i=0; i<ITERATION_COUNT; i++)
{
var angle = Math.floor(Math.random() * 360);
var test3 = (200 * sinArray[angle]);

//End i loop
}

var time2 = new Date();

//This somewhat unwieldy procedure is how we find out the elapsed time ...

var msec1 = (time1.getUTCSeconds() * 1000) + time1.getUTCMilliseconds();
var msec2 = (time2.getUTCSeconds() * 1000) + time2.getUTCMilliseconds();

var elapsed1 = msec2 - msec1;

outData += "Test 3 : Elapsed time is " + elapsed1.toString().trim() + " milliseconds<br><br>";

//Now comparison test with the same number of sin() calls ...

var time1 = new Date();

for (var i=0; i<ITERATION_COUNT; i++)
{
var angle = Math.floor(Math.random() * 360);
var test3 = (200 * Math.sin((Math.PI * angle) / 180));

//End i loop
}

var time2 = new Date();

var msec1 = (time1.getUTCSeconds() * 1000) + time1.getUTCMilliseconds();
var msec2 = (time2.getUTCSeconds() * 1000) + time2.getUTCMilliseconds();

var elapsed2 = msec2 - msec1;

outData += "Test 4 : Elapsed time is " + elapsed2.toString().trim() + " milliseconds<br><br>";

ref.innerHTML = outData;

//End function
}
``````

``````Test 3 : Elapsed time is 153 milliseconds

Test 4 : Elapsed time is 67 milliseconds
``````

``````Test 3 : Elapsed time is 167 milliseconds

Test 4 : Elapsed time is 69 milliseconds
``````

``````Test 3 : Elapsed time is 265 milliseconds

Test 4 : Elapsed time is 107 milliseconds
``````

``````Test 3 : Elapsed time is 162 milliseconds

Test 4 : Elapsed time is 69 milliseconds
``````

## 优化器已歪曲结果。

``````{

func : function (){
var i,a,b;
D2R = 180 / Math.PI
b = 0;
for (i = 0; i < count; i++ ) {
// single test start
a = (Math.random() * 360) | 0;
b += Math.sin(a * D2R);
// single test end
}
},
name : "summed",
},{
func : function (){
var i,a,b;
D2R = 180 / Math.PI;
b = 0;
for (i = 0; i < count; i++ ) {
// single test start
a = (Math.random() * 360) | 0;
b = Math.sin(a * D2R);
// single test end
}
},
name : "unsummed",
},
``````

``````=======================================
Performance test. : Optimiser check.
Use strict....... : false
Duplicates....... : 4
Samples per cycle : 100
Tests per Sample. : 10000
---------------------------------------------
Test : 'summed'
Calibrated Mean : 173µs ±1µs (*1) 11160 samples 57,803,468 TPS
---------------------------------------------
Test : 'unsummed'
Calibrated Mean : 0µs ±1µs (*1) 11063 samples Invalid TPS
----------------------------------------
Calibration zero : 140µs ±0µs (*)
(*) Error rate approximation does not represent the variance.
(*1) For calibrated results Error rate is Test Error + Calibration Error.
TPS is Tests per second as a calculated value not actual test per second.
``````

Java脚本中的基准测试充满了陷阱。使用质量基准，并知道优化器能做什么。

### 登录和查找测试。

``````tests : [{
func : function (){
var i,a,b;
b=0;
for (i = 0; i < count; i++ ) {
a = (Math.random() * 360) | 0;
b += a;
}
},
name : "Calibration",
},{
func : function (){
var i,a,b;
b = 0;
for (i = 0; i < count; i++ ) {
a = (Math.random() * 360) | 0;
b += array[a];

}
},
name : "lookup",
},{
func : function (){
var i,a,b;
b = 0;
for (i = 0; i < count; i++ ) {
a = (Math.random() * 360) | 0;
b += Math.sin(a);
}
},
name : "Sin",
}
],
``````

``````=======================================
Performance test. : Lookup compare to calculate sin.
Use strict....... : false
Data view........ : false
Duplicates....... : 4
Cycles........... : 1055
Samples per cycle : 100
Tests per Sample. : 10000
---------------------------------------------
Test : 'Calibration'
Calibrator Mean : 107µs ±1µs (*) 34921 samples
---------------------------------------------
Test : 'lookup'
Calibrated Mean : 6µs ±1µs (*1) 35342 samples 1,666,666,667TPS
---------------------------------------------
Test : 'Sin'
Calibrated Mean : 169µs ±1µs (*1) 35237 samples 59,171,598TPS
-All ----------------------------------------
Mean : 0.166ms Totals time : 17481.165ms 105500 samples
Calibration zero : 107µs ±1µs (*);
(*) Error rate approximation does not represent the variance.
(*1) For calibrated results Error rate is Test Error + Calibration Error.
TPS is Tests per second as a calculated value not actual test per second.
``````