Я только что написал целую рекламу о том, как я достиг этой точки, но решил, что легче опубликовать код и оставить его на этом:)
Насколько я могу судить, производительность test3 () должна быть такой же, как test1 () - единственное отличие состоит в том, где происходит исключение (внутри вызывающего метода для test1 (), внутри вызываемого метода для test3). ())
Почему test3 () регулярно занимает некоторое время между test1 () и test2 () для завершения?
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
public class Test {
public static void main(String[] args) {
warmup();
test1(2500000); // Exception caught inside the loop
test2(2500000); // Exception caught outside the loop
test3(2500000); // Exception caught "inside" the loop, but in the URLEncoder.encode() method
}
private static void warmup() {
// Let URLEncoder do whatever startup it needs before we hit it
String encoding = System.getProperty("file.encoding");
try {
URLEncoder.encode("ignore", encoding);
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private static void test1(int count) {
String encoding = System.getProperty("file.encoding");
long start = System.currentTimeMillis();
for (int i = 0; i < count; i++) {
try {
URLEncoder.encode("test 1 " + i, encoding);
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
long end = System.currentTimeMillis();
System.out.println("Performed " + count + " encodings trying to catch each in " + (end - start) + "ms");
}
private static void test2(int count) {
String encoding = System.getProperty("file.encoding");
long start = System.currentTimeMillis();
try {
for (int i = 0; i < count; i++) {
URLEncoder.encode("test 2" + i, encoding);
}
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
long end = System.currentTimeMillis();
System.out.println("Performed " + count + " encodings trying to catch all in " + (end - start) + "ms");
}
private static void test3(int count) {
long start = System.currentTimeMillis();
for (int i = 0; i < count; i++) {
URLEncoder.encode("test 3 " + i);
}
long end = System.currentTimeMillis();
System.out.println("Performed " + count + " encodings with a deprecated method in " + (end - start) + "ms");
}
}
При запуске он дает мне (JDK 1.6.0_13 в Windows XP) вывод:
Performed 2500000 encodings trying to catch each in 4906ms
Performed 2500000 encodings trying to catch all in 2454ms
Performed 2500000 encodings with a deprecated method in 2953ms
Итак, ответы довольно близки (мы говорим о чем-то, что настолько тривиально, что это неактуально), но мне любопытно!
Позже ...
Люди предположили, что мешает оптимизация JVM - я согласен. Итак, я разбил каждый тест на отдельный метод класса / main и каждый в отдельности. Результаты от этого:
1 - Performed 2500000 encodings trying to catch each in 5016ms
1 - Performed 5000000 encodings trying to catch each in 7547ms
1 - Performed 5000000 encodings trying to catch each in 7515ms
1 - Performed 5000000 encodings trying to catch each in 7531ms
2 - Performed 2500000 encodings trying to catch all in 4719ms
2 - Performed 5000000 encodings trying to catch all in 7250ms
2 - Performed 5000000 encodings trying to catch all in 7203ms
2 - Performed 5000000 encodings trying to catch all in 7250ms
3 - Performed 2500000 encodings with a deprecated method in 5297ms
3 - Performed 5000000 encodings with a deprecated method in 8015ms
3 - Performed 5000000 encodings with a deprecated method in 8063ms
3 - Performed 5000000 encodings with a deprecated method in 8219ms
Интересные наблюдения:
- Разрыв между перехватом каждого вызова и перехватом всего, что находится за пределами цикла, сокращается в его собственной JVM (я полагаю, что оптимизация не идет полным ходом в случае всех тестов в одном из-за других итераций, выполняется)
- Разрыв между try / catch на моей стороне и try / catch внутри URLEncoder.encode () теперь намного меньше (полсекунды за 5000000 итераций), но все же есть ...