java - Java中可变参数方法的性能

标签 java performance

我有一个关于参数数量可变的 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/

相关文章:

java - 如何分析 App Engine Java 上的实际内存使用情况?

c++ - vector of vector的初始化很慢

python - 在 python 中将 timedelta 转换为 int 非常慢

performance - 构建用于多键查找的快速 Excel VBA UDF

java - 我无法检索可用 cookie 的列表

java - 对 int 类型进行比较

php - MySQL:查询另一个查询结果并返回两个结果?

.net - 在 .NET 中读取和解析文件 - Performance For Hire

java - 在java中的WildcardFileFilter中需要帮助

java - Java 找不到 PHP 脚本,但可以在浏览器中运行