2013-06-17 3 views
1

Я собираю карту из плитки. Как часть этого, у меня есть метод, который заполняет оставшуюся часть карты со случайными зависимыми от ландшафта BufferedImages, когда важные части были нарисованы. Метод fillIn принимает два аргумента - arraylist BufferedImages и ArrayList из целых чисел. Целые элементы имеют вид, например, 90,92,94,96,98,100 и представляют проценты - два массива ArrayList имеют одинаковый размер, и этот пример будет означать, что 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; 
        } 
       }     
      } 
      } 
     } 
} 

ответ

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. Это может привести к замедлению вашего кода.
+0

Упс, извините. «Println» - это отладочная вещь, поэтому я могу проверить, работает ли цикл. Извините, что я его оставил. – MrB

+0

Хотя WOW! Принимая это, становится абсолютным миром разницы – MrB

+0

@MrB Я знаю, что это было раньше, и я был удивлен разницей также:: '' '' '' System.out.println' в основном делает это печать в файл (в этом случае стандартный выход), поэтому он так долго. – Doorknob

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

+0

Спасибо за ссылку. Очень полезно – MrB

1

Я сомневаюсь, что возникновение случайных чисел является проблемой (хотя вам следует избегать создания нового экземплярана каждой итерации).

Вместо этого это, вероятно, самая внутренняя петля. Ваш поиск - O (n), и это должно быть возможно сделать в O (log n). Если размер вашего списка велик, в среднем это будет иметь большое значение.

Например, взгляните на TreeMap.lowerKey().

+0

Спасибо. Я взгляну на это – MrB

Смежные вопросы