加速大量的Random.nextint调用

时间:2013-06-17 12:42:57

标签: java performance random bufferedimage

我正在从一个瓷砖组中整理一张地图。作为其中的一部分,我有一个方法,一旦绘制了重要的部分,用随机地形相关的BufferedImages填充地图的其余部分。 fillIn方法有两个参数 - BufferedImages的arraylist和Integers的ArrayList。整数的形式,例如,90,92,94,96,98,100,并代表百分比 - 两个ArrayLists具有相同的大小,这个例子意味着第一个瓷砖有90%的可能性,2%第二个等等(实际上,你会在我的代码中注意到,这也不完全正常。这不是问题,我知道如何修复它。还没有完成。)

地图是千瓦方块,填充此地图的速度令人无法接受。加速这项工作是否有任何提示或技巧?真的,我喜欢它的速度不明显。

鉴于复杂性,SSCE最终不会很短,但fillIn方法的代码如下,如果其他任何部分有用,请告诉我。

    private void fillIn (ArrayList<BufferedImage> b, ArrayList <Integer> r){
    for (int i=0; i<FULLGRIDSIZE; i++){
        for (int j=0; j<FULLGRIDSIZE; j++){
            if (mapArray[i][j] ==null){
                Random rand = new Random();
                int random = rand.nextInt(100);
                for (int loopVar =0 ;loopVar<r.size();loopVar++){
                    System.out.println(random +" "+ loopVar);
                    if (random < r.get(loopVar)){
                        mapArray[i][j] = b.get(loopVar);
                        break;
                    }
                }                   
            }
            }
        }
}

3 个答案:

答案 0 :(得分:2)

private void fillIn (ArrayList<BufferedImage> b, ArrayList <Integer> r){
    Random rand = new Random();
    for (int i=0; i<FULLGRIDSIZE; i++){
        for (int j=0; j<FULLGRIDSIZE; j++){
            if (mapArray[i][j] ==null){
                // Random rand = new Random(); Don't create so many Randoms!
                int random = rand.nextInt(100);
                for (int loopVar =0 ;loopVar<r.size();loopVar++){
                    // System.out.println(random +" "+ loopVar);
                    // printlns take a surprisingly long time
                    if (random < r.get(loopVar)){
                        mapArray[i][j] = b.get(loopVar);
                        break;
                    }
                }                   
            }
        }
    }
}
  1. 每个循环都不需要新的Random
  2. 不要System.out.println。它可以使您的代码速度惊人。

答案 1 :(得分:1)

你应该有一个随机的生成器对象,可以尝试只打印一次。

 Random rand = new Random();

private void fillIn (ArrayList<BufferedImage> b, ArrayList <Integer> r){
    String out = "";
    for (int i=0; i<FULLGRIDSIZE; i++){
        for (int j=0; j<FULLGRIDSIZE; j++){
            if (mapArray[i][j] ==null){
                int random = rand.nextInt(100);
                for (int loopVar =0 ;loopVar<r.size();loopVar++){
                    out += random +" "+ loopVar + "\n";
                    if (random < r.get(loopVar)){
                        mapArray[i][j] = b.get(loopVar);
                        break;
                    }
                }                   
            }
        }
    }
    System.out.println(out);
}

并分析更改http://demesos.blogspot.com/2011/09/replacing-java-random-generator.html

的随机生成器

答案 2 :(得分:1)

我怀疑随机数生成是问题(尽管你应该避免在每次迭代时创建一个新的Random实例)。

相反,它可能是最里面的循环。您的查找是O(n),应该可以在O(log n)中执行。如果您的列表大小很大,平均而言会产生巨大的差异。

例如,请查看TreeMap.lowerKey()