1.最初是有一道題,寫一個方法返回是否奇偶數。
題目如下。
https://www.codingsky.com/doc/2020/3/22/929.html
最終我寫了如下測試代碼
public class Main {
public static void main(String[] args) {
test1();
test2();
}
public static void test1() {
int number = Integer.MAX_VALUE;//分別取值10萬、100萬、1000萬、1億
int a = 1;
long start = System.currentTimeMillis();
for (int j = 1; j < number; j++) {
for (int i = 1; i < number; i++) {
boolean ret = isOdd(i);
}
}
long end = System.currentTimeMillis();
System.out.println("第1種" +(end - start) + "毫秒");
}
public static void test2() {
int number = Integer.MAX_VALUE;//分別取值10萬、100萬、1000萬、1億
int a = 1;
long start2 = System.currentTimeMillis();
for (int j = 1; j < number; j++) {
for (int i = 1; i < number; i++) {
boolean ret2 = isOdd2(i);
}
}
long end2 = System.currentTimeMillis();
System.out.println("第2種" + (end2 - start2) + "毫秒");
}
public static boolean isOdd(int i) {
return i % 2 != 0;
}
public static boolean isOdd2(int i) {
return (i & 1) == 1;
}
}
測試好多次,結論果然如上文章所說,兩種差不多
二、但同時網上也有人給出結論說
位運算與 和取模運算 &比%具有更高的效率
https://blog.csdn.net/kris1025/article/details/104577813
關鍵代碼
public class Main {
public static void main(String[] args) {
test1();
test2();
}
public static void test1() {
int number = Integer.MAX_VALUE;//分別取值10萬、100萬、1000萬、1億
int a = 1;
long start = System.currentTimeMillis();
for (int i = 1; i < number; i++) {
a %= i;
}
long end = System.currentTimeMillis();
System.out.println("第1種" +(end - start) + "毫秒");
}
public static void test2() {
int number = Integer.MAX_VALUE;//分別取值10萬、100萬、1000萬、1億
int a = 1;
long start2 = System.currentTimeMillis();
for (int i = 1; i < number; i++) {
a &= i;
}
long end2 = System.currentTimeMillis();
System.out.println("第2種" + (end2 - start2) + "毫秒");
}
我親自運行代碼測試了下,也是正確的。
那到底誰對呢?
後來我又發現其實上面說取模運算快的,例子取餘的數一直在變。也就是上面的i。
而求奇偶數中餘上的數固定是2.
這裏又研究看到了另二篇文章,才明白原因。
這裏貼下結論
通過原理來計算取餘和取模總結:
- fix 函數是向 0 方向舍入取整,取餘操作計算餘數步驟爲:
- n=fix(x除以y)
- rem(x,y)=x-n*y
參考如下:
https://mp.csdn.net/console/editor/html/106809391
再結合計算機乘法,和除法的計算原理。
https://www.cnblogs.com/stigerzergold/p/10328472.html
最終才知道兩者爲何原因。是因爲求餘,會轉換爲除法和乘法。所以餘數大了,計算機底層的操作步驟就多了。所以運算的耗時。
所以把上述代碼改成如下。你會發現時間也差不多。
public class Main {
public static void main(String[] args) {
// for (int i = 0; i < 10; i++) {
//
// }
test1();
test2();
}
public static void test1() {
int number = Integer.MAX_VALUE;//分別取值10萬、100萬、1000萬、1億
int a = 1;
long start = System.currentTimeMillis();
for (int j = 1; j < number; j++) {
for (int i = 1; i < number; i++) {
// boolean ret = isOdd(i);
a = i % 2;
// n = i/2(左移<<1), a = i - (n * 2)
// a = i - (i << 1 >> 1);
}
}
long end = System.currentTimeMillis();
System.out.println("第1種" +(end - start) + "毫秒");
}
public static void test2() {
int number = Integer.MAX_VALUE;//分別取值10萬、100萬、1000萬、1億
int a = 1;
long start2 = System.currentTimeMillis();
for (int j = 1; j < number; j++) {
for (int i = 1; i < number; i++) {
// boolean ret2 = isOdd2(i);
a = i & 1;
}
}
long end2 = System.currentTimeMillis();
System.out.println("第2種" + (end2 - start2) + "毫秒");
}
後面再附一個位運算的奇技淫巧