Java开关循环复杂度与性能 [英] java switch cyclomatic complexity vs performance

查看:95
本文介绍了Java开关循环复杂度与性能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我这里有一个案例,其中switch语句包含大约40个案例,每个案例都基于输入返回不同的配置对象。该方法显示出度量标准的环复杂性过高,通常我会将其更改为处理程序对象映射。但是此开关位于其中性能至关重要的一段代码中,因此我想到了一个问题:如何将HashMap查找和处理程序调用与性能方面的开关块进行比较。有人比较过吗?值得考虑吗?还是对于有限数量的int键有更快的查找对象?

I have a case here where the switch statement contains about 40 cases of each returning a different configured object based on input. This method is shown as having too high cyclomatic complexity in the metrics and usually I would change this into a map of handler objects. But this switch sits in a piece of code where performance is all-important so I came up with the question of how a HashMap lookup and handler call compares to a switch block execution performance-wise. Anyone compared that yet? Is it worth considering? Or is there any faster lookup object for a finite number of int keys?

干杯,
Kai

Cheers, Kai

推荐答案

似乎搜索值比切换方法要快一些。
因此,如果您的代码更改经常集中在散列方法上,那么如果它经过精打细算并且不会经常更改,则可以使用切换方法而不会造成损失。如果您的应用程序是由多个程序员开发的,则您应该更喜欢使用散列方法,而不是防止将来的错误

It seems that searching the values is slightly faster than switch approach. So if your code changes often focus on the hash approach, if it's polished and not going to change often you can use the switch approach without remorsals. If your application is in development by several programmers you should prefer the hash approach to prevent future bugs.

开关版本:27.32191395 ns。哈希版本:26.98444367 ns。

Switch version: 27.32191395 ns. Hash version: 26.98444367 ns.

使用哈希获得的时间:1.23%。

Time gained with hash: 1.23%.

我使用以下代码对其进行了测试代码:

I tested it with the following code:

导入java.util.Random;

import java.util.Random;

/**
 * @author ruslan.lopez
 */
public class CyclomaticVsHash {

    private static final Random RNG    = new Random();
    static int[]                myHash = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
            12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
            29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40 };

    /**
     * @param args
     *            the command line arguments
     */
    public static void main(String[] args) {
        long iterations = 100000000;
        warmUp(iterations);
        System.out.println("Cycle1");
        double individualTime = getAverageTimePerIterationc1(iterations);
        iterations = 10000;
        double totalTime = getTotalTimec1(iterations);

        System.out.println("ns/iteration: " + individualTime);
        System.out.println("Total time for " + iterations + " runs: "
                           + totalTime);

        System.out.println("Cycle2");
        iterations = 100000000;
        warmUp(iterations);
        double individualTime1 = getAverageTimePerIterationc2(iterations);
        iterations = 10000;
        double totalTime1 = getTotalTimec2(iterations);

        System.out.println("ns/iteration: " + individualTime1);
        System.out.println("Total time for " + iterations + " runs: "
                           + totalTime1);

    }

    public static void warmUp(long iterations) {
        System.out.println("Starting warmup");
        for (int i = 0; i < iterations; i++) {
            runCycles();
            runCycles1();
        }
    }

    public static double getAverageTimePerIterationc1(long iterations) {
        // test
        System.out.println("Starting individual time test");
        long timeTaken = 0;
        for (int i = 0; i < iterations; i++) {
            long startTime = System.nanoTime();
            runCycles();
            timeTaken += System.nanoTime() - startTime;
        }
        return (double) timeTaken / iterations;
    }

    public static long getTotalTimec1(long iterations) {
        // test
        System.out.println("Starting total time test");
        long timeTaken = 0;
        for (int i = 0; i < iterations; i++) {
            long startTime = System.nanoTime();
            runCycles();
            timeTaken += System.nanoTime() - startTime;
        }
        return timeTaken;
    }

    public static double getAverageTimePerIterationc2(long iterations) {
        // test
        System.out.println("Starting individual time test");
        long timeTaken = 0;
        for (int i = 0; i < iterations; i++) {
            long startTime = System.nanoTime();
            runCycles1();
            timeTaken += System.nanoTime() - startTime;
        }
        return (double) timeTaken / iterations;
    }

    public static long getTotalTimec2(long iterations) {
        // test
        System.out.println("Starting total time test");
        long timeTaken = 0;
        for (int i = 0; i < iterations; i++) {
            long startTime = System.nanoTime();
            runCycles1();
            timeTaken += System.nanoTime() - startTime;
        }
        return timeTaken;
    }

    private static void runCycles() {
        Integer num = RNG.nextInt();
        int newnum;
        switch (num) {
            case 1:
                newnum = num * 1;
                break;
            case 2:
                newnum = num * 2;
                break;
            case 3:
                newnum = num * 3;
                break;
            case 4:
                newnum = num * 4;
                break;
            case 5:
                newnum = num * 5;
                break;
            case 6:
                newnum = num * 6;
                break;
            case 7:
                newnum = num * 7;
                break;
            case 8:
                newnum = num * 8;
                break;
            case 9:
                newnum = num * 9;
                break;
            case 10:
                newnum = num * 10;
                break;
            case 11:
                newnum = num * 11;
                break;
            case 12:
                newnum = num * 12;
                break;
            case 13:
                newnum = num * 13;
                break;
            case 14:
                newnum = num * 14;
                break;
            case 15:
                newnum = num * 15;
                break;
            case 16:
                newnum = num * 16;
                break;
            case 17:
                newnum = num * 17;
                break;
            case 18:
                newnum = num * 18;
                break;
            case 19:
                newnum = num * 19;
                break;
            case 20:
                newnum = num * 20;
                break;
            case 21:
                newnum = num * 21;
                break;
            case 22:
                newnum = num * 22;
                break;
            case 23:
                newnum = num * 23;
                break;
            case 24:
                newnum = num * 24;
                break;
            case 25:
                newnum = num * 25;
                break;
            case 26:
                newnum = num * 26;
                break;
            case 27:
                newnum = num * 7;
                break;
            case 28:
                newnum = num * 28;
                break;
            case 29:
                newnum = num * 29;
                break;
            case 30:
                newnum = num * 30;
                break;
            case 31:
                newnum = num * 31;
                break;
            case 32:
                newnum = num * 32;
                break;
            case 33:
                newnum = num * 33;
                break;
            case 34:
                newnum = num * 34;
                break;
            case 35:
                newnum = num * 35;
                break;
            case 36:
                newnum = num * 36;
                break;
            case 37:
                newnum = num * 37;
                break;
            case 38:
                newnum = num * 38;
                break;
            case 39:
                newnum = num * 39;
                break;
            default:
                newnum = num * 40;
                break;
        }
    }

    private static void runCycles1() {
        Integer num = RNG.nextInt();
        int nwenum = num > 0 && num < 39
                                        ? myHash[num - 1]
                                        : myHash[39];
    }
}

这篇关于Java开关循环复杂度与性能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆