代码之家  ›  专栏  ›  技术社区  ›  Dead Programmer

删除结尾处的分隔符

  •  -2
  • Dead Programmer  · 技术社区  · 14 年前
    String prefix = "";
    for (String serverId : serverIds) {
      sb.append(prefix);
      prefix = ",";
      sb.append(serverId);
    }
    

    下面的代码比上面的代码运行得快。“prefix”对象在每次迭代中都会创建不必要的对象。上面的代码需要86324纳秒,而我的代码只需要68165纳秒。

    List<String> l =  Arrays.asList("SURESH1","SURESH2","SURESH4","SURESH5");
    StringBuffer  l1 = new StringBuffer();
    int sz = l.size(); 
    int i=0; long t =
    System.nanoTime();
    for (String s : l)
    { 
       l1.append(s);     
       if  ( i != sz-1)
            l1.append(",");   i++;
       } 
    } 
    long t2 = System.nanoTime();
    System.out.println ((t2-t)); System.out.println(l1);
    
    // The time taken for the above code is 68165 nano seconds
    SURESH1,SURESH2,SURESH4,SURESH5
    

    请告诉我哪一个在你看来更好。

    2 回复  |  直到 14 年前
        1
  •  2
  •   Jon Skeet    14 年前

    有几点:

    • 我的代码不需要你预先知道元素的数量。换句话说,它可以在任何情况下工作 Iterable<String>
    • StringBuffer 而不是 StringBuilder ?
    • “空前缀对象”只创建一次。。。您有多确定代码中没有任何对空字符串文本的引用?
    • 你觉得哪种代码更容易阅读?在大多数情况下,这可能比时机更重要(当前发布的代码似乎没有足够的大括号,例如…)
    • Joiner 班级)?
    • 不要在基准测试中使用这么小的计时。你期望你的系统时钟有多精确?你应该多次重复同样的操作,直到花费了合理的时间。

    编辑:现在解决第一个问题的一个替代方法是:

    boolean first = true;
    StringBuilder builder = new StringBuilder();
    for (String value : values) {
      if (first) {
        first = false;
      } else {
        builder.append(",");
      }
      builder.append(value);
    }
    

    或者如果你真的喜欢使用计数器:

    int i = 0;
    StringBuilder builder = new StringBuilder();
    for (String value : values) {
      if (i != 0) {
        builder.append(",");
      }
      builder.append(value);
      i++;
    }
    
        2
  •  0
  •   Stephen C    14 年前

    我对您编写和运行基准测试的方式也有严重的怀疑。首先,计时表明您的代码没有进行JIT编译。人们在使用Java基准测试时会犯很多错误,这些错误会使结果无效。给我们看完整的代码。

    另一点是,在大多数情况下,这种微优化与实际程序的性能无关。要么程序已经运行得够快了,要么你在浪费时间优化程序的错误部分。

    推荐文章