一道面试题的实验
class Test
{
public static void main(String[] args)
{
Date a=new Date(),b;
for(int i=0;i<2000000000;i++){
if(i%2==0){};
}
b=new Date();
System.out.println(b.getTime()-a.getTime());
b=new Date();
for(int i=0;i<2000000000;i++){
if((i&1)==0){};
}
a=new Date();
System.out.println(a.getTime()-b.getTime());
}
}
测试平台是CPU:P8400 2.26GHz ,2G DDR3内存运行上面代码得出结果都在6秒之上,两者相差不大,有时位运算所花的时间甚至比取余还多。
为了验证在C语言下的情况,特地下了一个Turbo C 2.0的编译器,程序代码如下
#include <dos.h>
main(){
long i;
struct time st,et;
gettime(&st);
for(i=0;i<100000000L;i++){
if(i%2==0){;}
}
gettime(&et);
printf("%d\n",(et.ti_min-st.ti_min) * 60 * 100+(et.ti_sec-st.ti_sec)*100+et.ti_hund-st.ti_hund);
gettime(&st);
for(i=0;i<200000000L;i++){
if(i&1==0){;}
}
gettime(&et);
printf("%d",(et.ti_min-st.ti_min) * 60 * 100+(et.ti_sec-st.ti_sec)*100+et.ti_hund-st.ti_hund);
}
这段代码运行次数有点不同,取余运算1亿次,位运算运算2亿次,原因是取余实在太慢了,等不及。结果是取余基本在27秒左右,而位运算保持在0.7秒左右看来真如预料,C语言中的位运算和取余完全不在一个数量级上.但让人不解的是,为啥C语言的取余居然没有JAVA这种中间语言快呢.
晚上回到家,又用家里的台式机试验了一下.家里的运行环境是:CPU E5200 2.5GHz 内存 2G DDR2 800MHz
JAVA代码相同,运行几次后这回有差距了, 取余运算一直在5秒以上,而位运算一直是1秒多一点. 难道和CPU的运算指令有关? 末了也测试了一下在C环境下的情况,这回用的是VC 6.0环境,使用C++语言,代码如下
#include <iostream>
#include <ctime>
using namespace std;
int main(){
clock_t s;
unsigned int i,max=2E8;
s=clock();
cout<<max<<endl;
for(i=1;i<max;i++)
{if(i%2==0){;}}
cout<<(clock()-s)<<endl;
s=clock();
for(i=1;i<max;i++)
{if(i&1==0){;}}
cout<<(clock()-s)<<endl;
return 0;
}
使用DEBUG模式,因为使用Release模式结果总是0即使把循环次数剩以10,还是如此(可见VC的效率了)。
这样运算的结果相差不多,都是在0.3-0.4秒之间,这样看不出差别,基本这此时间都是浪费在循环上了,里面的运算没有耗费多少时间,因为我尝试将里面的语句注释掉,运行的时间差别不大。
总结:
另外篇头的面试题,前面的问题“如何知道一个数是不是2的N次方” 答案是 X<<1 看是否为0