public class sdfsd { public static void main(String[] args){ int a=1; int b=3; a=a^b; b=b^a; a=a^b; System.out.println(b); System.out.println(a); } } 个人认为这只是技巧罢了
int a=1; int b=2; a^=b; b^=a; a^=b; System.out.print(a); System.out.print(b);
这种方法稍微有点问题,就是怕a+b之和超出int的最大值int a = int.MaxValue; int b = int.MaxValue - 1; Console.WriteLine("a={0};b={1}", a, b); a = a + b; b = a - b; a = a - b; Console.WriteLine("a={0};b={1}", a, b); 测试结果,a,b确实互换了
这种方法稍微有点问题,就是怕a+b之和超出int的最大值int a = int.MaxValue; int b = int.MaxValue - 1; Console.WriteLine("a={0};b={1}", a, b); a = a + b; b = a - b; a = a - b; Console.WriteLine("a={0};b={1}", a, b); 测试结果,a,b确实互换了 刚测试了一下也是这样,我开始想当然了,谢谢指正。
我的二代i5-2410测试出来
478
728然后我所有的10000000多加一个0,得出
4749
7190不知道你用的是什么奇葩机器,可能优化不一样的
我觉得重点应该是for循环里面变量声明问题,
第一个循环i声明了1次,j1000次
第二个i1次,j10000000次
老紫竹大大的博客供参考。。
http://blog.csdn.net/java2000_net/article/details/4314894
我哪里不对讲请指出。。
int a=1;
int b=2;
在不使用临时变量的情况下用三行代码交换a、b的值。
public static void main(String[] args) {
int[] a=new int[1000];
int[] b=new int[10000000];
long start = System.currentTimeMillis();
//method 1
for(int i=0;i<1000;i++){
for(int j=0;j<10000000;j++){
// a[i]++;
}
}
long end = System.currentTimeMillis();
System.out.print(end-start+"\t");
start=System.currentTimeMillis();
//method 2
for(int i=0 ;i<10000000;i++){
for(int j=0;j<1000;j++){
// b[i]++;
}
}
end = System.currentTimeMillis();
System.out.println(end-start); }
测试结果:
3704 4095
3625 3860
3609 3877
3609 4001
测试2:恢复赋值(同楼主代码)
测试结果:
23616 22096
23048 21986
24164 22495
23532 22175结果分析:
1、通过测试1(仅循环切换耗时)可以证明6楼的所说,第一段代码从内层循环切到外层的次数为 1000次;第二段代码从内层循环切到外层的次数为10000000次,所以切换多的耗时多2、通过测试2看到加上赋值后第一段代码明显耗时明显增加,两段代码赋值次数都一样,但是第一段代码每一个数组元素都是从1-10000000赋值,存大赋值大数据所以我觉得整体来说大赋值大数据耗时会比较多
public class sdfsd {
public static void main(String[] args){
int a=1;
int b=3;
a=a^b;
b=b^a;
a=a^b;
System.out.println(b);
System.out.println(a);
}
}
个人认为这只是技巧罢了
int b=2;
a^=b;
b^=a;
a^=b;
System.out.print(a);
System.out.print(b);
此外,4楼提到的变量声明次数也是一个原因。
总结下:
1、变量声明次数:method 1中 i 声明1次,j 声明了1000次,method 2中,i声明了1次,j声明了10000000次;
2、循环切换:内层循环和外层循环切换次数,method 1为1000次,method 2为10000000次;
3、数据存储:method 2中内层循环累加10000000次,数据非常大,而method 2仅仅累加了1000次;11楼的测试说明了单独考虑第3条因素,大套小的循环会比小套大更快,因为数据相对较小,存储效率高。但是综合三种因素考虑,在数据大小相当,变量声明都只用一次的情况下,循环切换的时间会比较关键。
昨天笔试的时候啥都没多想就选了小套大,我认为他应该考的就是循环切换的耗时。
不知说的是否恰当,请各位指正
a=a+b; //a=3 b=2
b=a-b; //a=3 b=1
a=a-b; //a=2 b=1
把int替换为正整数 是不是就不用怕溢出了 溢2次 就互换了
这个题目我选的是t2快,感性认识和11L的不谋而合
汗,表示压力很大啊
int b = int.MaxValue - 1;
Console.WriteLine("a={0};b={1}", a, b);
a = a + b;
b = a - b;
a = a - b;
Console.WriteLine("a={0};b={1}", a, b);
测试结果,a,b确实互换了
int b = int.MaxValue - 1;
Console.WriteLine("a={0};b={1}", a, b);
a = a + b;
b = a - b;
a = a - b;
Console.WriteLine("a={0};b={1}", a, b);
测试结果,a,b确实互换了
刚测试了一下也是这样,我开始想当然了,谢谢指正。
b= a-b;
a= a-b;
因为a[i]和b[i]都是一个内存查找的动作,而a[i]只查找了1000次,b[i]却查找了10000000次。a[i]更多地击中了CPU的缓存(快),而b[i]更多地进行了内存查找(慢)。于是乎这就是一个micro bench的问题了。Java的micro bench是很难的,也没有什么绝对公平的方法。难点在于JVM的JIT。对于进行micro bench的方法,首先要进行预热,其次要进行统计。
预热的概念是让JVM先行运行该方法若干次(关键词:compile threshold),使其JIT对方法进行优化和编译。
统计的意思是运行多次测试,取平均值、中值、标准差等数据进行综合比较。
另外要注意的一点是,绝对不能在同一个程序里面测试两种方法。要编译测试两个方法的不同版本分别进行测试,否则会有干扰。以下是我的测试方法:这个测试里面我没有用统计方法,因为结果已经很明显了:方法一比方法二快了2.5倍左右package test;public class Test { static int[] a = new int[100];
static int[] b = new int[100000]; public static void main(final String[] args) throws Exception { // warm up
for (int i = 0; i < 5000; i++)
method2(); long start = System.currentTimeMillis();
for (int i = 0; i < 1000; i++)
method2();
long end = System.currentTimeMillis();
System.out.println(end - start);
} static void method1() {
for (int i = 0; i < 100; i++) {
for (int j = 0; j < 100000; j++) {
a[i]++;
}
}
} static void method2() {
for (int i = 0; i < 100000; i++) {
for (int j = 0; j < 100; j++) {
b[i]++;
}
}
}
}
这是方法二的测试代码,你想要测方法一,只需要把main里面的method2改成method1
推断考点是这个。
int a;
int b;
a = a + b;
b = a - b;
a = a - b;
java是跑在虚拟机上的,这种硬件依赖,虚拟机依赖的题一点意义也没有。