行为相同的条件检查的执行[重复]

2024-04-04

我回答了这个问题 https://stackoverflow.com/questions/25234401/which-is-a-better-practice-for-if-else-condition/25234523并在运行代码时注意到一些让我感兴趣的东西。问题的一部分是关于各种类型的相同条件检查的性能,例如:

if (x > 0) { 
    if (y > 0) { 
        if (z > 0) { 
            if (complexCondition()) { 
                 noOp();
            }
        }
    }
}

versus

if (x > 0 && y > 0 && z > 0 && complexCondition()) { 
     noOp();
}

我写了一个程序,计算执行一定次数的迭代需要多长时间,结果是我不明白的。

这是我的程序在我的计算机上的输出(Win 8.1 64 位、javac 1.8.0_11 (Oracle)、java 1.0.0_11 (Java SE、Oracle)。我已经多次运行每个试验,它们产生可重复的结果。

x = 9, y = 2, z = 8, countTrials = 1, iterationsPerTrial = 2736000
Method        Average Runtime(ns)
guardIf()     5746173
multipleIf()  4868180
chainedIf()   9316172

x = 9, y = 2, z = 8, countTrials = 100, iterationsPerTrial = 2736000
guardIf()     1642750
multipleIf()  1121897
chainedIf()   1739522

x = -1, y = 2, z = 8, countTrials = 1, iterationsPerTrial = 2736000 // I expect shorter results with x = -1, because they all short curcuit
guardIf()     9245313
multipleIf()  8728608
chainedIf()   11718332

x = -1, y = 2, z = 8, countTrials = 100, iterationsPerTrial = 2736000 
guardIf()     1754279
multipleIf()  1611278
chainedIf()   4947295

毫秒测量(通过以下方式实现)org.apache.commons.lang3.time.StopWatch)

x = 9, y = 2, z = 8, countTrials = 1, iterationsPerTrial = Integer.MAX_VALUE
Method        Average Runtime(ms)
guardIf()     1664
multipleIf()  1095
chainedIf()   1654

x = -1, y = 2, z = 8, countTrials = 1, iterationsPerTrial = Integer.MAX_VALUE
Method        Average Runtime(ms)
guardIf()     4886
multipleIf()  4926
chainedIf()   4862

x = 9, y = 2, z = 8, countTrials = 10, iterationsPerTrial = Integer.MAX_VALUE
Method        Average Runtime(ms)
guardIf()     1673
multipleIf()  1108
chainedIf()   1682

x = -1, y = 2, z = 8, countTrials = 10, iterationsPerTrial = Integer.MAX_VALUE
Method        Average Runtime(ms)
guardIf()     4364
multipleIf()  4363
chainedIf()   4877

为什么所有方法的运行都需要更长的时间(在这种情况下chainIf,几乎多了 300% 的时间)当他们检查的值允许他们全部短路时?

我已经用调试器逐步完成了所有这些,并且它们实际上确实短路了(正如我所期望的)。我检查了字节码并且chainedIf() and multipleIf()完全相同。我感到困惑和好奇。

我不确定我执行测量的方式是否存在一些缺陷,因此我在下面包含了我的程序。

节目来源

class TrialResult {
    public long GuardIf = 0; 
    public long MultipleIf = 0; 
    public long ChainedIf = 0; 

    public TrialResult(long guardIf, long multipleIf, long chainedIf) { 
        this.GuardIf = guardIf; 
        this.MultipleIf = multipleIf; 
        this.ChainedIf = chainedIf; 
    }
}

public class Program {

    private int x; 
    private int y; 
    private int z; 

    public static void main(String[] args) { 
        Program program = new Program(); 
        List<TrialResult> trials = new ArrayList<TrialResult>(); 
        int countTrials = 1; 

        for (int j = 0; j < countTrials; j++) {     
            long t0 = 0, t1 = 0; 

            t0 = System.nanoTime();
            for (long i = 0; i < 2073600; i++) { 
                program.chainedIf();
            }
            t1 = System.nanoTime();
            long chainIf = t1 - t0;

            t0 = System.nanoTime();
            for (long i = 0; i < 2073600; i++) { 
                program.multipleIf();
            }

            t1 = System.nanoTime();
            long multipleIf = t1 - t0;

            t0 = System.nanoTime();
            for (long i = 0; i < 2073600; i++) { 
                program.guardIf();
            }
            t1 = System.nanoTime();
            long guardIf = t1 - t0;
            System.out.printf("Trial %d completed\r\n", j+1);

            trials.add(new TrialResult(guardIf, multipleIf, chainIf)); 
        }

        long chainIf = 0, multipleIf = 0, guardIf = 0; 
        for (TrialResult r : trials) { 
            chainIf += r.ChainedIf; 
            multipleIf += r.MultipleIf; 
            guardIf += r.GuardIf; 
        }
        System.out.printf("%d, %d, %d", guardIf / trials.size(), multipleIf / trials.size(), chainIf / trials.size()); 
    }

    private Program() {
        x = 9; 
        y = 2; 
        z = 8; 
    }

    private void chainedIf() { 
        if (x > 0) { 
            if (y > 0) { 
                if (z > 0) { 
                    if (complexCondition()) { 
                         noOp();
                    }
                }
            }
        }
    }

    private void multipleIf() { 
        if (x > 0 && y > 0 && z > 0 && complexCondition()) { 
             noOp();
        }
    }

    public void guardIf() { 
        if (x <= -1) { 
            return; 
        }

        if (y <= -1) { 
            return; 
        }

        if (z <= -1) { 
            return; 
        }

        if (!complexCondition()) { 
            return; 
        }

         noOp();
    }

    private boolean complexCondition() { 
        return (x > 0 && 
            y < x && 
            y + z > x
        );      
    }

    private void noOp() { 
        return; 
    }
}

当所有方法检查的值都允许短路时,为什么所有方法的运行都需要更长的时间(在 chainIf 的情况下,几乎多出 300% 的时间)?

因为你的基准是错误的。请阅读类似问题的答案:
Java 循环在运行几次后变慢/JIT 的错误? https://stackoverflow.com/questions/24882946/java-loop-gets-slower-after-some-runs-jits-fault/24889503#24889503

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

行为相同的条件检查的执行[重复] 的相关文章

随机推荐

  • 替代嵌套在另一个表单中的 Ajax 上传表单

    我有一个 HTML 表单来编辑我工作地点的数据库系统中人员的详细信息 表单的一部分允许用户上传该人的照片 然而 这给我带来了麻烦 因为我试图让用户上传图片并在提交要保存的人员详细信息之前看到它已成功上传 从而使表单更加 Ajax y 给我带
  • 如何将 SketchUp 模型导出到 Three.js?

    我通过谷歌创建了一个模型SketchUp 我想将其导出到three js节省一些时间 因为我想使用SketchUp比three js 那么有人可以告诉我该怎么做吗 非常感谢 您可以从 SketcUp 导出 collada DAE 然后使用
  • 移动包含子模块的 git 工作副本

    Git 最近的一项变化改变了 git使用子模块时处理目录 而不是拥有一个 git每个子模块 现在所有内容都位于 根级别 git目录 与包括子模块的工作副本相对应的目录 然后 在每个子模块中 创建一个文件 该文件指向该子模块的新位置 git目
  • 如何在kivy项目中隐藏python代码文件和其他相关文件

    我最近在 Google Play 上发布了一个用 Python Kivy 编写的 Android 应用程序 通常 build py 脚本会将整个项目文件包装到一个文件夹中 即应用程序包文件夹 但是 如果我在安装 apk 后检查手机上这个包的
  • 为什么我们需要 crossCheckMatching 功能?

    我正在阅读很多使用特征提取 sift ecc 进行对象检测的文章 在计算两个图像上的描述符后 为了获得良好的匹配 他们使用了 crossCheckMatching 发现于样本 cpp descritpor extractor matcher
  • 如何在角度6中实现内容显示更多和显示更少

    我们有 6 个内容分区 我们还使用字符限制每个 div 我们使用 Bootstrap 4 Angular 6 版本 6 div 一些切换 div 内容打开 一些关闭 https i stack imgur com dS04r jpg这个案例
  • 如何在 AppKit 上的自定义 SwiftUI 表单中右对齐项目标签?

    我有以下可可形式 struct Canvas PreviewProvider static var previews some View VStack HStack alignment firstTextBaseline Text Endp
  • 如何访问React路由器中的历史堆栈?

    我正在尝试访问反应路由器的历史堆栈 这是我想做的 我使用react js 和react router 创建一个板 如果用户单击板上的列表之一 则会转到详细信息页面 假设用户点击列表中 id 为 3 的文章 react router 会转到
  • 如何让 CameraX 预览在拍照时冻结?

    我的自定义 CameraX 流程如下 打开相机预览 实时 点击按钮拍照 单击该按钮时有一个过程 将路径转换为位图 旋转图像 自动裁剪图像 保存到设备中 运行所有进程并成功后 将图像发送到其他Fragment并将其显示为glide 问题是何时
  • 如何更改所有 UITableViewCell 的背景颜色

    我有一个非常简单的视图控制器 它只有一个UITableView and a UIButton 当点击按钮时 我想改变所有的背景颜色UITableViewCells变为绿色 假设有一些单元格不可见 我使用此循环来完成我需要的操作 IBActi
  • 使用 SQLAlchemy 计算具有条件的行数

    我有一个像这样的 sqlite 表 其中有 3 列 我想要 计算 user id 1 的行数 SQLAlchemy 可以做到这一点吗 class UserImage db Model id db Column db Integer prim
  • mac OSX 10.8.3 文件系统上的 gae 本地数据存储在哪里?

    我已经尝试了这些帖子中的所有建议 有谁知道 Mac OS X 的 Google App Engine 本地数据存储文件位于哪里 https stackoverflow com questions 15753914 does anyone k
  • 添加动态 formControl 时,所有必需输入字段的文本颜色更改为无效颜色

    每当我通过按钮单击添加动态 formControl 时 所需的所有输入字段都会将颜色更改为无效 红色 我的期望是 只有当输入被 触摸 时 表单字段才会更改为无效颜色 并且仅在特定的非全部 我不知道为什么会发生这种情况 我刚刚接触有角度和有角
  • 在 Silverlight 中检测控件的焦点

    有什么方法可以判断某个控件 特别是 System Windows Controls TextBox 是否在 Silverlight 中获得焦点 我正在寻找类似以下内容的内容 您会在常规 Net 应用程序中看到的内容 textBox Focu
  • Swift 3 中的 NSFastEnumeration

    我正在尝试迭代一个对象CMSensorDataList返回的类CMSensorRecorder accelerometerData from to 该类确认NSFastEnumeration协议 所以我尝试了中提到的技巧https stac
  • JUnit 运行测试命令行

    我有以下结构 lib junit 4 10 jar tests Tester java tests Tester class build jar jar file jar 测试器属于包测试 我可以使用编译测试 javac cp build
  • App Engine SDK DevServer 只读模式?

    有没有办法以只读模式运行应用程序引擎开发服务器 以模拟 Google 的定期维护 从而将数据存储区置于只读模式 在定期维护期间优雅降级 http code google com appengine docs python howto mai
  • 如何映射输入文件数组?

    我有两个函数 一个将文件转换为 dataUrl 另一个返回结果的承诺 fileToDataURL file var reader new FileReader return new Promise function resolve reje
  • 我可以使用 <%= ... %> 在 ASP.NET 中设置控件属性吗?

  • 行为相同的条件检查的执行[重复]

    这个问题在这里已经有答案了 我回答了这个问题 https stackoverflow com questions 25234401 which is a better practice for if else condition 25234