V8中JS与C++性能测试对比

Posted on June 20, 2016

测试方法

预先在JS端构造1000w组随机数据,每组数据四个数值,代表:x,y,width,height。然后将所有测试数据传入Native,确保JS和Native测试的数据是完全相同的。

var data = [];
var i, t, x, y, width, height, index, start;
for (i = 0; i < SIZE; i++) {
    x = parseInt(Math.random() * 100);
    y = parseInt(Math.random() * 100);
    width = parseInt(Math.random() * 100);
    height = parseInt(Math.random() * 100);
    data.push(x, y, width, height);
}

分别在JS端和Native遍历这1000w组数据,执行Matrix.transformBounds(rect)方法以及transformBoundsNoField(x,y,width,height)函数。前者是一个类方法,执行过程会读写类实例上的属性。后者是纯数学函数,不带任何属性读写。

var index = 0;
for (var i = 0; i < SIZE; i++) {
    var x = data[index++];
    var y = data[index++];
    var width = data[index++];
    var height = data[index++];
    rectJS.setTo(x, y, width, height);
    matrixJS.transformBounds(rectJS);
}
var index = 0;
for (var i = 0; i < SIZE; i++) {
    var x = data[index++];
    var y = data[index++];
    var width = data[index++];
    var height = data[index++];
    transformBoundsNoField(x, y, width, height);
}

测试结果

  1. JS耗时:509ms(纯JS测试耗时,执行JS版的Matrix.transformBounds类方法)
  2. JS-NoField耗时:441ms(不含属性读写的纯JS测试耗时,执行JS版的transformBoundsNoField函数)
  3. JSBinding耗时:700ms(绑定方式测试耗时,将原生端的Matrix类绑定为JS对象执行Matrix.transformBounds方法)
  4. Native耗时:188ms(纯Native测试耗时,执行Native版的Matrix.transformBounds类方法)
  5. Native-NoField耗时:188ms(不含属性读写的纯Native测试耗时,执行Native版本的transformBoundsNoField函数)

测试结论

  1. 从测试结果(1)与(2)对比可以看出JS端不读写属性会有约15%性能提升。
  2. 从测试结果(4)与(5)对比可以看出Native端是否读写属性没有任何区别,属性读写在Native端的开销基本可以忽略。
  3. 从测试结果(3)跟其他结果对比可以看出无论哪种情况,JS绑定Native对象的方式都是最慢的。
  4. Native端运行性能大约是JS端的 2.3~2.7 倍。其中测试(1)含有属性读写的情况更加符合实际使用场景。2.7倍左右更有参考价值。

测试Demo

https://github.com/domchen/V8Performace