有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java为什么Groovy的Map比Array更具可伸缩性?

我今天遇到了这个问题,我不明白为什么groovy阵列在变大时的伸缩性不如Map

在我的示例中,我创建了一个映射(LinkedHashMap)和一个字符串数组(String[])。然后我从0迭代到10^7,将I插入到映射或数组中。我做了10次,以确保异常值不会扰乱结果

int max = 10**7
int numTests = 10

long totalTimeMap = 0
long totalTimeArray = 0

numTests.times{
    long start = System.currentTimeMillis()

    Map m = [:]
    max.times {
        m[it] = "${it}"
    }

    long end = System.currentTimeMillis()
    totalTimeMap += (end-start)
}

numTests.times {
    long start = System.currentTimeMillis()

    String[] s = new String[max]
    max.times{
        s[it] = "${it}"
    }

    long end = System.currentTimeMillis()
    totalTimeArray += (end-start)
}

println "Map: ${totalTimeMap}"
println "Array: ${totalTimeArray}"

输出是意外的,因为映射的性能优于数组:

Map: 49361
Array: 101123

我用java做了同样的实验:

public static void main(String[] args) {

        int max = 10000000;
        int numTests = 10;

        long totalTimeMap = 0;
        long totalTimeArray = 0;

        for(int i=0; i<numTests; i++){
            long start = System.currentTimeMillis();

            Map m = new LinkedHashMap();
            for(int j=0; j<max; j++){
                m.put(j, "" + j);
            }

            long end = System.currentTimeMillis();
            totalTimeMap += (end-start);
        }

        for(int i=0; i<numTests; i++){
            long start = System.currentTimeMillis();

            String[] s = new String[max];
            for(int j=0; j<max; j++){
                s[j] = "" + j;
            }

            long end = System.currentTimeMillis();
            totalTimeArray += (end-start);
        }

        System.out.println("Map: " + totalTimeMap);
        System.out.println("Array: " + totalTimeArray);
    }

并且输出是预期的(阵列速度比映射速度快):

Map: 34564
Array: 12822

我的问题是:为什么在使用Groovy时Map比数组快


共 (1) 个答案

  1. # 1 楼答案

    在Groovy中将字符串添加到数组中时,您正在创建一个模板化字符串,然后将其转换回java字符串(模板化完成后),因为它必须适合String[]

    对于Map版本,您只存储了一个模板字符串,因此不需要进行任何计算

    以下基准测试代码:

    @Grab('org.gperfutils:gbench:0.4.3-groovy-2.4')
    
    int max = 10000
    
    new groovyx.gbench.BenchmarkBuilder().run {
        'Array' {
            String[] s = new String[max]
            max.times { int idx ->
                s[idx] = Integer.toString(idx)
            }  
        }
        'List' {
            def s = []
            max.times{
                s << "${it}"
            }  
        }
        'Map' {
            Map m = [:]
            max.times {
                m[it] = "${it}"
            }
        }
    }.prettyPrint()
    

    在数组方法中不使用GroovyString的情况下,给出了以下结果:

    * Groovy: 2.4.3
    * JVM: Java HotSpot(TM) 64-Bit Server VM (25.45-b02, Oracle Corporation)
        * JRE: 1.8.0_45
        * Total Memory: 800.5 MB
        * Maximum Memory: 1820.5 MB
    * OS: Mac OS X (10.10.3, x86_64)
    
    Options
    =======
    * Warm Up: Auto (- 60 sec)
    * CPU Time Measurement: On
    
              user  system      cpu     real
    
    Array  1819502    6491  1825993  1833209
    List   1697948    6533  1704481  1724448
    Map    2040521    8932  2049453  2116760