本贴的代码 效率测试均在该贴提供的框架 下进行:
http://bbs.9ria .com/thread-57015-1-2.html
测试环境:FlashCS5 Professional
系统:WindowsXP_SP2
CPU:AMD Athlon(tm) 64 Processor 1.81GHz
内存:2.50GB
防火墙全部处于关闭状态
数学类代码优化的基本原则:
1) 位运算及条件运算比四则运算快,加减比乘除快,乘除比取模快,整型比浮点型快,int比uint快。
2) Math类函数大多都很慢,应尽量用级别较低的运算符或者原生函数替代。
3) 在某些数学运算中,运用字符串函数进行处理会更为方便,也能提高可读性,但在效率优先的场合不推荐使用。
本贴讨论三种取整算法 (向下,四舍五入,向上),下一贴探讨正弦函数的算法优化。
1 取整函数:
向下取整可以运用Math.floor,int及位运算:
function MathFloor(__num:Number):int{//Math.floor
return Math.floor(__num);
}
function intFloor(__num:Number):int{//int
return int(__num);
}
function bitLeftFloor(__num:Number):int{//位左移运算
return (__num)<<0;
}
function bitRightFloor(__num:Number):int{//位右移运算
return (__num)>>0;
}
function convert(__num:Number):int{//直接返回值,仅作类型转换
return __num;
}
----------效率测试开始----------
Math.floor取整函数执行300000次所耗费的时间为226毫秒
int取整函数执行300000次所耗费的时间为142毫秒
左位移取整函数执行300000次所耗费的时间为141毫秒
右位移取整函数执行300000次所耗费的时间为134毫秒
转换取整函数执行300000次所耗费的时间为135毫秒
----------效率测试结束----------
----------效率测试开始----------
Math.floor取整函数执行300000次所耗费的时间为275毫秒
int取整函数执行300000次所耗费的时间为164毫秒
左位移取整函数执行300000次所耗费的时间为138毫秒
右位移取整函数执行300000次所耗费的时间为127毫秒
转换取整函数执行300000次所耗费的时间为126毫秒
----------效率测试结束----------
----------效率测试开始----------
Math.floor取整函数执行300000次所耗费的时间为229毫秒
int取整函数执行300000次所耗费的时间为138毫秒
左位移取整函数执行300000次所耗费的时间为145毫秒
右位移取整函数执行300000次所耗费的时间为151毫秒
转换取整函数执行300000次所耗费的时间为137毫秒
----------效率测试结束----------
显然,Math.floor最慢,而int,位运算和直接转换的速度基本接近。由于在AS3中,int函数实际上不是取整运算,而是类型转换,故速度不逊色于位运算。
四舍五入取整,如不希望用Math.round,可以对当前数值加0.5,再向下取整:
function MathRound(__num:Number):int{
return Math.round(__num);
}
function intRound(__num:Number):int{
return int(__num+0.5);
}
function bitLeftRound(__num:Number):int{
return (__num+0.5)<<0;
}
function bitRightRound(__num:Number):int{
return (__num+0.5)>>0;
}
function convertRound(__num:Number):int{
return __num+0.5;
}
----------效率测试开始----------
Math.round四舍五入函数执行300000次所耗费的时间为217毫秒
int取整函数执行300000次所耗费的时间为131毫秒
左位移四舍五入函数执行300000次所耗费的时间为155毫秒
右位移四舍五入函数执行300000次所耗费的时间为138毫秒
类型转换四舍五入函数执行300000次所耗费的时间为157毫秒
----------效率测试结束----------
----------效率测试开始----------
Math.round四舍五入函数执行300000次所耗费的时间为222毫秒
int取整函数执行300000次所耗费的时间为141毫秒
左位移四舍五入函数执行300000次所耗费的时间为137毫秒
右位移四舍五入函数执行300000次所耗费的时间为132毫秒
类型转换四舍五入函数执行300000次所耗费的时间为142毫秒
----------效率测试结束----------
----------效率测试开始----------
Math.round四舍五入函数执行300000次所耗费的时间为268毫秒
int取整函数执行300000次所耗费的时间为188毫秒
左位移四舍五入函数执行300000次所耗费的时间为166毫秒
右位移四舍五入函数执行300000次所耗费的时间为170毫秒
类型转换四舍五入函数执行300000次所耗费的时间为168毫秒
----------效率测试结束----------
结果跟向下取整相似
向上取整相对麻烦,需要检测当前的数是否整数,也可以用int(value+1-Number.MIN_VALUE)代替。注:Number.MIN_VALUE为常数,不必担心会影响效率。
function MathCeil(__num:Number):int{
return Math.ceil(__num);
}
function intCeilCondition(__num:Number):int{
return (int(__num)==__num)?(__num):int(__num+1);
}
function intCeil(__num:Number):int{
return int(__num+1-Number.MIN_VALUE);
}
function bitLeftCeilCondition(__num:Number):int{
return ((__num<<0)==__num)?(__num):int((__num+1)<<0);
}
function bitLeftCeil(__num:Number):int{
return (__num+1-Number.MAX_VALUE)<<0;
}
function bitRightCeilCondition(__num:Number):int{
return ((__num>>0)==__num)?(__num):int((__num+1)>>0);
}
function bitRightCeil(__num:Number):int{
return (__num+1-Number.MAX_VALUE)>>0;
}
--------传小数作为参数的测试结果---------
----------效率测试开始----------
Math.ceil向上取整函数执行300000次所耗费的时间为217毫秒
条件+int取整函数执行300000次所耗费的时间为154毫秒
int+Number.MIN_VALUE取整函数执行300000次所耗费的时间为160毫秒
左位移+条件取整函数执行300000次所耗费的时间为158毫秒
左位移+Number.MIN_VALUE取整函数执行300000次所耗费的时间为173毫秒
右位移+条件取整函数执行300000次所耗费的时间为151毫秒
右位移+Number.MIN_VALUE取整函数执行300000次所耗费的时间为162毫秒
----------效率测试结束----------
----------效率测试开始----------
Math.ceil向上取整函数执行300000次所耗费的时间为199毫秒
条件+int取整函数执行300000次所耗费的时间为155毫秒
int+Number.MIN_VALUE取整函数执行300000次所耗费的时间为165毫秒
左位移+条件取整函数执行300000次所耗费的时间为154毫秒
左位移+Number.MIN_VALUE取整函数执行300000次所耗费的时间为152毫秒
右位移+条件取整函数执行300000次所耗费的时间为150毫秒
右位移+Number.MIN_VALUE取整函数执行300000次所耗费的时间为155毫秒
----------效率测试结束----------
----------效率测试开始----------
Math.ceil向上取整函数执行300000次所耗费的时间为215毫秒
条件+int取整函数执行300000次所耗费的时间为150毫秒
int+Number.MIN_VALUE取整函数执行300000次所耗费的时间为168毫秒
左位移+条件取整函数执行300000次所耗费的时间为153毫秒
左位移+Number.MIN_VALUE取整函数执行300000次所耗费的时间为172毫秒
右位移+条件取整函数执行300000次所耗费的时间为149毫秒
右位移+Number.MIN_VALUE取整函数执行300000次所耗费的时间为151毫秒
----------效率测试结束----------
--------***********---------
--------传整数作为参数的测试结果---------
----------效率测试开始----------
Math.ceil向上取整函数执行300000次所耗费的时间为216毫秒
条件+int取整函数执行300000次所耗费的时间为164毫秒
int+Number.MIN_VALUE取整函数执行300000次所耗费的时间为167毫秒
左位移+条件取整函数执行300000次所耗费的时间为136毫秒
左位移+Number.MIN_VALUE取整函数执行300000次所耗费的时间为157毫秒
右位移+条件取整函数执行300000次所耗费的时间为146毫秒
右位移+Number.MIN_VALUE取整函数执行300000次所耗费的时间为147毫秒
----------效率测试结束----------
----------效率测试开始----------
Math.ceil向上取整函数执行300000次所耗费的时间为225毫秒
条件+int取整函数执行300000次所耗费的时间为157毫秒
int+Number.MIN_VALUE取整函数执行300000次所耗费的时间为162毫秒
左位移+条件取整函数执行300000次所耗费的时间为134毫秒
左位移+Number.MIN_VALUE取整函数执行300000次所耗费的时间为158毫秒
右位移+条件取整函数执行300000次所耗费的时间为152毫秒
右位移+Number.MIN_VALUE取整函数执行300000次所耗费的时间为149毫秒
----------效率测试结束----------
----------效率测试开始----------
Math.ceil向上取整函数执行300000次所耗费的时间为224毫秒
条件+int取整函数执行300000次所耗费的时间为150毫秒
int+Number.MIN_VALUE取整函数执行300000次所耗费的时间为162毫秒
左位移+条件取整函数执行300000次所耗费的时间为130毫秒
左位移+Number.MIN_VALUE取整函数执行300000次所耗费的时间为190毫秒
右位移+条件取整函数执行300000次所耗费的时间为184毫秒
右位移+Number.MIN_VALUE取整函数执行300000次所耗费的时间为191毫秒
----------效率测试结束----------
--------***********---------
传小数作为参数时,用MIN_VALUE与条件运算结果相近,传整数时,条件运算速度略高于MIN_VALUE。两算法的差别在于,前者多一步条件,后者多一个减运算。因此,本结果也是条件优于四则运算的一个体现。因此,在实际应用 中,依然推荐使用条件运算符进行向上取整。