4 дек. 2008 г.

Java :: just for fun iteration

Шальным ветром довелось мне взглянуть на код одного корпоративного проекта... думал видел индусского когда много, но такое заставило откровенно поржать
// Collection collection определён ранее
try{
Iterator it = collection.iterator();
while(true){
Object next = it.next();
// некоторые действия с next - не суть важно какие
}
}catch(NoSuchElementException e){
}

Updated: В результате некоторого диалога с Бассом всё же решил в числах сравнить «эффект» вышеописанного подхода и традиционного:
public class TestIteration {

@Test
public void test(){
subTest(20);
subTest(500);
subTest(2000);
subTest(5000);
}

private void subTest(final int size) {
final int count = 10000;
Collection<String> c = new ArrayList<String>(size);
for(int i = 0; i < size; i++){
c.add(Integer.toHexString(i));
}

long time1 = 0;
for(int i = 0; i < count; i++){
time1 -= System.currentTimeMillis();

int charCount = 0;
try{
final Iterator<String> iterator = c.iterator();
while(true){
final String next = iterator.next();
// некоторое действие всё же надо сделать, дабы потенциально jit не выкинул next
charCount += next.length();
}
}catch(NoSuchElementException e){
// nothing do
}

time1 += System.currentTimeMillis();
}

long time2 = 0;
for(int i = 0; i < count; i++){
time2 -= System.currentTimeMillis();

int charCount = 0;
for(final Iterator<String> iterator = c.iterator();iterator.hasNext();){
final String next = iterator.next();
charCount += next.length();
}

time2 += System.currentTimeMillis();
}

System.out.println("items:" + size);
System.out.println("time1:" + time1 + "ms, average:" + ((double)time1 / count) + "ms");
System.out.println("time2:" + time2 + "ms, average:" + ((double)time2 / count) + "ms");
System.out.println();
}
}

Результаты:
items:20
time1:234ms, average:0.0234ms
time2:23ms, average:0.0023ms

items:500
time1:182ms, average:0.0182ms
time2:132ms, average:0.0132ms

items:2000
time1:447ms, average:0.0447ms
time2:402ms, average:0.0402ms

items:5000
time1:767ms, average:0.0767ms
time2:966ms, average:0.0966ms

Результаты для использования в качестве коллекции HashSet:
items:20
time1:134ms, average:0.0134ms
time2:49ms, average:0.0049ms

items:500
time1:276ms, average:0.0276ms
time2:195ms, average:0.0195ms

items:2000
time1:742ms, average:0.0742ms
time2:653ms, average:0.0653ms

items:5000
time1:1645ms, average:0.1645ms
time2:1274ms, average:0.1274ms

Классический подход, как правило, быстрее индусского - и уж точно правильней и лучше читается.

1 комментарий:

Roman комментирует...

Жость. Это мне напоминает вот такой код

int i = 0;
char[] data = ...; //some array
try {
while(true) {
//do something with element accessed by index i
i++;
}
} catch(ArrayIndexOutOfBoundsException e) {
//the end
}

Этот код я видел не у индусов, а вполне себе у одного из наших программистов :) Надеюсь, чувак больше так не пишет.