Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/390.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/vim/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 这些陈述中的一种是否有好处_Java_Optimization - Fatal编程技术网

Java 这些陈述中的一种是否有好处

Java 这些陈述中的一种是否有好处,java,optimization,Java,Optimization,这两个片段之间有什么区别吗?表演可读性?否则呢 if (arg > 0) { for (int i = 0; i < arg; i++) { sb.append(">"); } } else if (arg < 0) { for (int i = 0; i < Math.abs(arg); i++) { sb.append("<"); } } if(arg>0){ 对于(int i=0;i”);

这两个片段之间有什么区别吗?表演可读性?否则呢

if (arg > 0) {
    for (int i = 0; i < arg; i++) {
        sb.append(">");
    }
} else if (arg < 0) {
    for (int i = 0; i < Math.abs(arg); i++) {
        sb.append("<");
    }
}
if(arg>0){
对于(int i=0;i”);
}
}else if(arg<0){
for(int i=0;i附加("如果如您所述,
arg
是一个常数,那么前者将更有效,因为您只计算一次If/else条件,而不是每次循环迭代时都计算它。但是,如果arg在每次循环迭代中都不是常数,那么您显然希望使用后者。

If
arg
小于0,循环将永远不会运行,因为
i
在开始时等于0,肯定不小于0


因此,如果
arg
小于0,则第二个选项的速度较慢,因为它将运行所有选项,而不管它是否为真。

我认为这两个选项都非常不可读。无论如何,关于速度:

  • 首先,衡量这一部分是否应该优化。大多数时候,答案是“不”
  • 如果答案恰好是“是”:尝试不同的变体并测量它们的性能
好的方面是JIT喜欢简单易读的代码

我只想

for (int i = 0; i < Math.abs(arg); i++) sb.append(arg > 0 ? ">" : "<");
但实际上有一个解决方案:

sb.append(Strings.repeat(arg > 0 ? ">" : "<", Math.abs(arg));

sb.append(Strings.repeat(arg>0?>):“我不喜欢它们中的任何一个:

  • 第一,因为当您已经知道符号时,不需要调用
    Math.abs()
  • 第二个,因为如果
    arg
    为负数,它不会终止。所以它在任何情况下都不等同于第一个。所以你在比较苹果和桔子

    • 我不会使用任何一个;我会尝试下面两个片段中的一个


      第一种变体

          char c = arg > 0 ? '>' : '<';
      
          int  n = Math.abs(arg);
      
          StringBuffer sb = new StringBuffer(n);
      
          for (int i = 0; i < n; ++i) {
      
              sb.append(c);
          }
      
          char c = arg > 0 ? '>' : '<';
      
          int  n = Math.abs(arg);
      
          char[] content = new char[n];
      
          Arrays.fill(content, c);
      
          StringBuffer sb = new StringBuffer(n);
      
          sb.append(content);
      
      在这里,我的建议是:

      • 与自写循环相比,更喜欢算法(上面的代码段根本没有循环)

      • 特别是,
        System.arraycopy()
        (由
        sb.append(char[])
        调用)是一个本机方法,它不会在每次迭代中执行绑定检查

      我个人更喜欢第二个版本,因为它是无循环的。它有一个缺点,它两次分配和接触
      内容
      对应的内存:第一次是当
      内容
      被填充时,然后当它被复制到
      字符串缓冲区


      最重要的是,分析您的代码以确保您没有这样做


      “想要速度?测量。”(by)

      查看生成的字节码。这些根本没有意义。“0到arg乘以1”,但是“arg<0"?这两个参数都不是常量。如果你想清楚地知道
      arg
      不会改变,那么
      final
      就足够了。@HovercraftFullOfEels:忘记字节码,它不会说明热代码的执行速度。如果代码不是热代码,那么就完全忘记它。它在现代JVM上不会更有效,因为它知道它不是但是它仍然是糟糕的代码。仅仅因为JVM可以清理你的混乱并不意味着它在逻辑上效率较低。
          char c = arg > 0 ? '>' : '<';
      
          int  n = Math.abs(arg);
      
          StringBuffer sb = new StringBuffer(n);
      
          for (int i = 0; i < n; ++i) {
      
              sb.append(c);
          }
      
          char c = arg > 0 ? '>' : '<';
      
          int  n = Math.abs(arg);
      
          char[] content = new char[n];
      
          Arrays.fill(content, c);
      
          StringBuffer sb = new StringBuffer(n);
      
          sb.append(content);