我有一个关于参数数量可变的 Java 方法性能的问题。
假设我有以下两种选择:
public static final boolean isIn(int i, int v1, int v2) {
return (v1 == i) || (v2 == i);
}
public static final boolean isIn(int i, int... values) {
for (int v : values) {
if (i == v) {
return true;
}
}
return false;
}
现在,当我的第一种方法的参数达到 20、30 甚至 50 个时,主要问题就来了。现在,那只会伤害眼睛。好的,这是遗留代码,我想用唯一的一个可变参数方法替换所有代码。
知道对性能有什么影响吗?编译器是否有机会对第二种方法进行一些优化,使其或多或少类似于第一种形式?
编辑: 好吧,也许我不够清楚。我对具有 50 个参数的方法没有性能问题。正如 Peter Lawrey 所说,这只是关于可读性。
我想知道如果我切换到参数数量可变的新方法会出现性能问题。
换句话说:如果您关心性能,最好的方法是什么?有 50 个参数的方法还是唯一一个有可变参数的方法?
最佳答案
我有同样的问题,于是转向实验。
public class ArgTest {
int summation(int a, int b, int c, int d, int e, int f) {
return a + b + c + d + e + f;
}
int summationVArgs(int... args) {
int sum = 0;
for (int arg : args) {
sum += arg;
}
return sum;
}
final static public int META_ITERATIONS = 200;
final static public int ITERATIONS = 1000000;
static public void main(String[] args) {
final ArgTest at = new ArgTest();
for (int loop = 0; loop < META_ITERATIONS; loop++) {
int sum = 0;
final long fixedStart = System.currentTimeMillis();
for (int i = 0; i < ITERATIONS; i++) {
sum += at.summation(2312, 45569, -9816, 19122, 4991, 901776);
}
final long fixedEnd = System.currentTimeMillis();
final long vargStart = fixedEnd;
for (int i = 0; i < ITERATIONS; i++) {
sum += at.summationVArgs(2312, 45569, -9816, 19122, 4991, 901776);
}
final long vargEnd = System.currentTimeMillis();
System.out.printf("%03d:%d Fixed-Args: %d ms\n", loop+1, ITERATIONS, fixedEnd - fixedStart);
System.out.printf("%03d:%d Vargs-Args: %d ms\n", loop+1, ITERATIONS, vargEnd - vargStart);
}
System.exit(0);
}
}
如果您在现代 JVM(此处为 1.8.0_20)上运行此代码,您会发现可变数量的参数会导致性能开销,并且还可能会消耗内存。
我只会发布前 25 次运行:
001:1000000 Fixed-Args: 16 ms
001:1000000 Vargs-Args: 45 ms
002:1000000 Fixed-Args: 13 ms
002:1000000 Vargs-Args: 32 ms
003:1000000 Fixed-Args: 0 ms
003:1000000 Vargs-Args: 27 ms
004:1000000 Fixed-Args: 0 ms
004:1000000 Vargs-Args: 22 ms
005:1000000 Fixed-Args: 0 ms
005:1000000 Vargs-Args: 38 ms
006:1000000 Fixed-Args: 0 ms
006:1000000 Vargs-Args: 11 ms
007:1000000 Fixed-Args: 0 ms
007:1000000 Vargs-Args: 17 ms
008:1000000 Fixed-Args: 0 ms
008:1000000 Vargs-Args: 40 ms
009:1000000 Fixed-Args: 0 ms
009:1000000 Vargs-Args: 89 ms
010:1000000 Fixed-Args: 0 ms
010:1000000 Vargs-Args: 21 ms
011:1000000 Fixed-Args: 0 ms
011:1000000 Vargs-Args: 16 ms
012:1000000 Fixed-Args: 0 ms
012:1000000 Vargs-Args: 26 ms
013:1000000 Fixed-Args: 0 ms
013:1000000 Vargs-Args: 7 ms
014:1000000 Fixed-Args: 0 ms
014:1000000 Vargs-Args: 7 ms
015:1000000 Fixed-Args: 0 ms
015:1000000 Vargs-Args: 6 ms
016:1000000 Fixed-Args: 0 ms
016:1000000 Vargs-Args: 141 ms
017:1000000 Fixed-Args: 0 ms
017:1000000 Vargs-Args: 139 ms
018:1000000 Fixed-Args: 0 ms
018:1000000 Vargs-Args: 106 ms
019:1000000 Fixed-Args: 0 ms
019:1000000 Vargs-Args: 70 ms
020:1000000 Fixed-Args: 0 ms
020:1000000 Vargs-Args: 6 ms
021:1000000 Fixed-Args: 0 ms
021:1000000 Vargs-Args: 5 ms
022:1000000 Fixed-Args: 0 ms
022:1000000 Vargs-Args: 6 ms
023:1000000 Fixed-Args: 0 ms
023:1000000 Vargs-Args: 12 ms
024:1000000 Fixed-Args: 0 ms
024:1000000 Vargs-Args: 37 ms
025:1000000 Fixed-Args: 0 ms
025:1000000 Vargs-Args: 12 ms
...
即使在最好的时候,Vargs-Args 也从未下降到 0 毫秒。
关于java - Java中可变参数方法的性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5727336/