测试方法
预先在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);
}
测试结果
- JS耗时:509ms(纯JS测试耗时,执行JS版的Matrix.transformBounds类方法)
- JS-NoField耗时:441ms(不含属性读写的纯JS测试耗时,执行JS版的transformBoundsNoField函数)
- JSBinding耗时:700ms(绑定方式测试耗时,将原生端的Matrix类绑定为JS对象执行Matrix.transformBounds方法)
- Native耗时:188ms(纯Native测试耗时,执行Native版的Matrix.transformBounds类方法)
- Native-NoField耗时:188ms(不含属性读写的纯Native测试耗时,执行Native版本的transformBoundsNoField函数)
测试结论
- 从测试结果(1)与(2)对比可以看出JS端不读写属性会有约15%性能提升。
- 从测试结果(4)与(5)对比可以看出Native端是否读写属性没有任何区别,属性读写在Native端的开销基本可以忽略。
- 从测试结果(3)跟其他结果对比可以看出无论哪种情况,JS绑定Native对象的方式都是最慢的。
- Native端运行性能大约是JS端的 2.3~2.7 倍。其中测试(1)含有属性读写的情况更加符合实际使用场景。2.7倍左右更有参考价值。
测试Demo
https://github.com/domchen/V8Performace