【发布时间】:2009-05-25 02:30:41
【问题描述】:
我刚刚写了一个关于我如何达到这一点的完整简介,但我认为发布代码并保留它更容易:)
据我所知,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");
}
}
运行它会给我(Windows XP 上的 JDK 1.6.0_13)输出:
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 优化会阻碍这一点 - 我同意。因此,我将每个测试分解为它自己的类/主方法,并且每个测试都单独进行。结果:
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 与 URLEncoder.encode() 中的 try/catch 之间的差距现在要小得多(超过 5000000 次迭代半秒),但仍然始终如一......
【问题讨论】:
-
以不同的顺序尝试测试:test2()、test3()、test1() 以隔离由于 JIT 编译造成的任何差异。
标签: java performance exception urlencode malformedurlexception