当我尝试解析 json 字符串时,遇到了与 switch 相关的奇怪性能问题。请引用下面的示例代码:
public class SwitchTest {
private static final String jsonString = "{\"person\":[{\"id\":-2147483648,\"firstName\":\"4809981875dc43ddb6d1add0b1eec75c><\\\"<//> ' \\\"\",\"lastName\":\"4809981875dc43ddb6d1add0b1eec75c\",\"address1\":\"4809981875dc43ddb6d1add0b1eec75c\",\"postCode\":\"4809981875dc43ddb6d1add0b1eec75c\",\"city\":\"4809981875dc43ddb6d1add0b1eec75c\",\"country\":\"4809981875dc43ddb6d1add0b1eec75c\",\"birthday\":\"2014-03-04T00:12:06Z\",\"active\":true},{\"id\":-2147483648,\"firstName\":\"3b21ba46239b484ea1d1b7d9dbee68c0><\\\"<//> ' \\\"\",\"lastName\":\"3b21ba46239b484ea1d1b7d9dbee68c0\",\"address1\":\"3b21ba46239b484ea1d1b7d9dbee68c0\",\"postCode\":\"3b21ba46239b484ea1d1b7d9dbee68c0\",\"city\":\"3b21ba46239b484ea1d1b7d9dbee68c0\",\"country\":\"3b21ba46239b484ea1d1b7d9dbee68c0\",\"birthday\":\"2014-03-04T00:12:06Z\",\"active\":true},{\"id\":-2147483648,\"firstName\":\"c953f8ebaaae4424a656c819b8149376><\\\"<//> ' \\\"\",\"lastName\":\"c953f8ebaaae4424a656c819b8149376\",\"address1\":\"c953f8ebaaae4424a656c819b8149376\",\"postCode\":\"c953f8ebaaae4424a656c819b8149376\",\"city\":\"c953f8ebaaae4424a656c819b8149376\",\"country\":\"c953f8ebaaae4424a656c819b8149376\",\"birthday\":\"2014-03-04T00:12:06Z\",\"active\":true},{\"id\":-2147483648,\"firstName\":\"d75587f037324efaafc88de095416221><\\\"<//> ' \\\"\",\"lastName\":\"d75587f037324efaafc88de095416221\",\"address1\":\"d75587f037324efaafc88de095416221\",\"postCode\":\"d75587f037324efaafc88de095416221\",\"city\":\"d75587f037324efaafc88de095416221\",\"country\":\"d75587f037324efaafc88de095416221\",\"birthday\":\"2014-03-04T00:12:06Z\",\"active\":true},{\"id\":-2147483648,\"firstName\":\"e8291a6104094e94b81daf4cf1852efe><\\\"<//> ' \\\"\",\"lastName\":\"e8291a6104094e94b81daf4cf1852efe\",\"address1\":\"e8291a6104094e94b81daf4cf1852efe\",\"postCode\":\"e8291a6104094e94b81daf4cf1852efe\",\"city\":\"e8291a6104094e94b81daf4cf1852efe\",\"country\":\"e8291a6104094e94b81daf4cf1852efe\",\"birthday\":\"2014-03-04T00:12:06Z\",\"active\":true},{\"id\":-2147483648,\"firstName\":\"63f0816b82eb42a8be9181e4a733285a><\\\"<//> ' \\\"\",\"lastName\":\"63f0816b82eb42a8be9181e4a733285a\",\"address1\":\"63f0816b82eb42a8be9181e4a733285a\",\"postCode\":\"63f0816b82eb42a8be9181e4a733285a\",\"city\":\"63f0816b82eb42a8be9181e4a733285a\",\"country\":\"63f0816b82eb42a8be9181e4a733285a\",\"birthday\":\"2014-03-04T00:12:06Z\",\"active\":true},{\"id\":-2147483648,\"firstName\":\"26019c0c46ef487dae175c1bae381417><\\\"<//> ' \\\"\",\"lastName\":\"26019c0c46ef487dae175c1bae381417\",\"address1\":\"26019c0c46ef487dae175c1bae381417\",\"postCode\":\"26019c0c46ef487dae175c1bae381417\",\"city\":\"26019c0c46ef487dae175c1bae381417\",\"country\":\"26019c0c46ef487dae175c1bae381417\",\"birthday\":\"2014-03-04T00:12:06Z\",\"active\":true},{\"id\":-2147483648,\"firstName\":\"a917a9d6628d4afea75ff6212df3bd32><\\\"<//> ' \\\"\",\"lastName\":\"a917a9d6628d4afea75ff6212df3bd32\",\"address1\":\"a917a9d6628d4afea75ff6212df3bd32\",\"postCode\":\"a917a9d6628d4afea75ff6212df3bd32\",\"city\":\"a917a9d6628d4afea75ff6212df3bd32\",\"country\":\"a917a9d6628d4afea75ff6212df3bd32\",\"birthday\":\"2014-03-04T00:12:06Z\",\"active\":true},{\"id\":-2147483648,\"firstName\":\"ef7663f41de648bf8d4a53e32ab0c386><\\\"<//> ' \\\"\",\"lastName\":\"ef7663f41de648bf8d4a53e32ab0c386\",\"address1\":\"ef7663f41de648bf8d4a53e32ab0c386\",\"postCode\":\"ef7663f41de648bf8d4a53e32ab0c386\",\"city\":\"ef7663f41de648bf8d4a53e32ab0c386\",\"country\":\"ef7663f41de648bf8d4a53e32ab0c386\",\"birthday\":\"2014-03-04T00:12:06Z\",\"active\":true},{\"id\":-2147483648,\"firstName\":\"c56ae519a31a4f478da29b9eac61a426><\\\"<//> ' \\\"\",\"lastName\":\"c56ae519a31a4f478da29b9eac61a426\",\"address1\":\"c56ae519a31a4f478da29b9eac61a426\",\"postCode\":\"c56ae519a31a4f478da29b9eac61a426\",\"city\":\"c56ae519a31a4f478da29b9eac61a426\",\"country\":\"c56ae519a31a4f478da29b9eac61a426\",\"birthday\":\"2014-03-04T00:12:06Z\",\"active\":true}]}";
private static int[] caseArray = new int[128];
static {
caseArray[','] = 1;
caseArray[':'] = 1;
caseArray['"'] = 1;
caseArray['{'] = 1;
caseArray['}'] = 1;
caseArray['['] = 1;
caseArray[']'] = 1;
}
@Test
public void testSwitchPerformance() {
long startTime = System.currentTimeMillis();
int loopNum = 100000;
for (int i = 0; i < loopNum; i++) {
switch_1();
}
long endTime = System.currentTimeMillis();
System.out.println("switch_1 took: " + (endTime - startTime));
startTime = System.currentTimeMillis();
for (int i = 0; i < loopNum; i++) {
switch_2();
}
endTime = System.currentTimeMillis();
System.out.println("switch_2 took: " + (endTime - startTime));
startTime = System.currentTimeMillis();
for (int i = 0; i < loopNum; i++) {
switch_3();
}
endTime = System.currentTimeMillis();
System.out.println("switch_3 took: " + (endTime - startTime));
startTime = System.currentTimeMillis();
for (int i = 0; i < loopNum; i++) {
switch_4();
}
endTime = System.currentTimeMillis();
System.out.println("switch_4 took: " + (endTime - startTime));
}
@Test
public void switch_1() {
char ch = 0;
for (int i = 0, len = jsonString.length(); i < len; i++) {
ch = jsonString.charAt(i);
switch (ch) {
case ',':
break;
case ':':
break;
case '"':
break;
case '{':
break;
case '}':
break;
case '[':
break;
case ']':
break;
default:
}
}
}
@Test
public void switch_2() {
int ch = 0;
for (int i = 0, len = jsonString.length(); i < len; i++) {
ch = jsonString.charAt(i);
switch (ch) {
case 1: // no char equals 1 in the json string.
break;
case ',':
break;
case ':':
break;
case '"':
break;
case '{':
break;
case '}':
break;
case '[':
break;
case ']':
break;
default:
}
}
}
@Test
public void switch_3() {
int ch = 0;
for (int i = 0, len = jsonString.length(); i < len; i++) {
ch = jsonString.charAt(i);
if (ch == ',') {
continue;
}
if (ch == ':') {
continue;
}
if (ch == '"') {
continue;
}
if (ch == '{') {
continue;
}
if (ch == '}') {
continue;
}
if (ch == ']') {
continue;
}
if (ch == '[') {
continue;
}
}
}
@Test
public void switch_4() {
int ch = 0;
for (int i = 0, len = jsonString.length(); i < len; i++) {
ch = jsonString.charAt(i);
if (caseArray[ch] > 0) {
continue;
}
}
}
}
这是运行结果:Windows 7/JDK1.7_51
switch_1 占用:474,switch_2 占用:5,switch_3 占用:6,switch_4 占用:129
switch_1 和 switch_2 之间的唯一区别是多了一个“情况 1:” 为什么 switch_1 这么慢?
最佳答案
switch_1,您的第一个基准测试,测量未进行 JIT 优化的代码的性能,以及 JIT 编译本身。
请运行 testSwitchPerformance 至少 3 次。
如果您进行更多这样的基准测试,我建议使用 JUnit benchmarks 。它会进行预热和基准测试运行并计算结果的平均值和标准偏差,以便您知道自己是否走在正确的道路上。
关于java开关性能优化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22182330/