java - 处理奇数和偶数元素的最有效方法是什么?

标签 java arrays

方法1

int[] arr = new int[10];
for(int i = 0; i < arr.length; i++) {
    if(i % 2 == 0)
       // do stuff
    else
       // do stuff
}

方法2

int[] arr = new int[10];
boolean flag = true;
for(int i = 0; i < arr.length; i++) {
    if(flag) {
       // do stuff
       flag = false;
    }
    else {
       // do stuff
       flag = true;
    }
}

方法3

int[] arr = new int[10];
for(int i = 0; i < arr.length; i++) {
    if((i & 1) == 1)
       // do stuff
    else
       // do stuff
}

方法4

int[] arr = new int[10];
for(int i = 0; i < arr.length; i+=2) {
   // do stuff for even numbers
}
for(int i = 1; i < arr.length; i+=2) {
   // do stuff for odd numbers
}

从方法 1 切换到方法 3 时,a guy got 66% performance boost.

在拥有大型团队的生产环境中,选择 2 和 3 之间的方法有何优点和缺点?

编辑

当您拥有分布式团队时,哪种方法是最好的方法,并且不会牺牲太多的可读性?

最佳答案

如果性能是你想要的,我愿意赌我的钱:

    for(int i = 0; i < arr.length; i+=2) {
        // do even stuff
    }
    for(int i = 1; i < arr.length; i+=2) {
        // do odd stuff
    }

这样你就可以跳过整个 if-else 部分。而且它的速度与“and”版本一样快。我来给你展示;这里我们有相同方法的 4 种不同实现:

private static long withModulus(int[] arr) {
    long elapsedTime = System.nanoTime();
    for(int i = 0; i < arr.length; i++) {
        List list;
        if ((i % 2) == 0) {
            list = new ArrayList<>();
            list.add(new Object());
        } else {
            list = new LinkedList<>();
            list.add(new Object());
        }
    }
    return (System.nanoTime() - elapsedTime);
}

private static long withFlag(int[] arr) {
    long elapsedTime = System.nanoTime();
    for(int i = 0; i < arr.length; i++) {
        List list;
        boolean flag = true;
        if (flag) {
            list = new ArrayList<>();
            list.add(new Object());
            flag = false;
        } else {
            list = new LinkedList<>();
            list.add(new Object());
            flag = true;
        }
    }
    return (System.nanoTime() - elapsedTime);
}

private static long withAnd(int[] arr) {
    long elapsedTime = System.nanoTime();
    for(int i = 0; i < arr.length; i++) {
        List list;
        if ((i & 1) == 1) {
            list = new ArrayList<>();
            list.add(new Object());
        } else {
            list = new LinkedList<>();
            list.add(new Object());
        }
    }
    return (System.nanoTime() - elapsedTime);
}

private static long withTwoLoops(int[] arr) {
    long elapsedTime = System.nanoTime();
    for(int i = 0; i < arr.length; i+=2) {
        List list;
        list = new ArrayList<>();
        list.add(new Object());
    }
    for(int i = 1; i < arr.length; i+=2) {
        List list;
        list = new LinkedList<>();
        list.add(new Object());
    }
    return (System.nanoTime() - elapsedTime);
}

现在是计时部分:

public static void main(String[] args) {
    int[] arr = new int[10000000];
    // Warm up
    withModulus(arr);
    withFlag(arr);
    withAnd(arr);
    withTwoLoops(arr);
    // Timing
    int iterations = 100;
    long meanModulus = 0, meanFlag = 0, meanAnd = 0, meanTwoLoops = 0;
    for (int i = 0; i < iterations; i++) {
        meanModulus += withModulus(arr);
    }
    for (int i = 0; i < iterations; i++) {
        meanFlag += withFlag(arr);
    }
    for (int i = 0; i < iterations; i++) {
        meanAnd += withAnd(arr);
    }
    for (int i = 0; i < iterations; i++) {
        meanTwoLoops += withTwoLoops(arr);
    }
    System.out.println("Modulus: "+(meanModulus/iterations)+" ms");
    System.out.println("Flag: "+(meanFlag/iterations)+" ms");
    System.out.println("And: "+(meanAnd/iterations)+" ms");
    System.out.println("Two loops: "+(meanTwoLoops/iterations)+" ms");
}

结果:

Modulus: 82331604 ms
Flag: 96305740 ms
And: 80845864 ms
Two loops: 79633999 ms

您可以尝试使用不同的数组大小,但对于大于 10000 的数组,两循环选项是最快的。
经过多次不同的运行和测试,有时“和”版本最快,有时“两个循环”版本最快。甚至“模数”版本在其中一项测试中也是最快的。在生产中,它主要取决于您在循环内执行的操作,而不是条件本身。

关于java - 处理奇数和偶数元素的最有效方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41158956/

相关文章:

java - 通过Java小程序或flash获取绝对文件路径

Java Servlet - 重定向 URL

java - 对集合的复杂断言

java - 如何声明不同数据类型的数组

java - 如何将 NSString 转换为字节数组

java - 关于内存泄漏和泛型方法

java - 它告诉我未实例化 Java 时的变量

c - 如何从字符数组中提取运算符?

arrays - Go中的JSON解码有符号整数数组

java - 如何创建包含 ArrayLists 的二维数组?