花时间运行需要一种方法

时间:2014-06-20 23:16:34

标签: java

我试图使用我通常用来获取持续时间的方法得到奇怪的结果:

float start = System.nanoTime();
//Do stuff
float duration = System.nanoTime() - start;
float durationInSeconds = duration / 1000000000.0f;

所以我尝试在这个手电筒应用程序中制作闪光灯:

public void onClick(DialogInterface dialog, int id) {

                isFlashOn = true;
                isStrobeActive = true;

                // Perform actual strobe
                strobeHandler.post(new Runnable() {
                    float currDuration = 0;
                    final float deltaTime = 1/60f;
                    final float deltaTimeInMil = deltaTime * 1000;

                    @Override
                    public void run() {
                        float strobePerSecond = 1 / currentStrobeValue;

                        if (!isStrobeLightOn) {
                            if (currDuration > strobePerSecond) {
                                params = camera.getParameters();
                                params.setFlashMode(Parameters.FLASH_MODE_TORCH);
                                camera.setParameters(params);
                                currDuration -= strobePerSecond;
                                isStrobeLightOn = true;
                            }
                        } else {
                            params = camera.getParameters();
                            params.setFlashMode(Parameters.FLASH_MODE_OFF);
                            camera.setParameters(params);
                            isStrobeLightOn = false;
                        }
                        currDuration += deltaTime;
                        strobeHandler.postDelayed(this, (long) deltaTimeInMil);
                    }
                });
            }

然而,日志返回0.0或3.052E-5。我不确定自己做错了什么,但我需要一些帮助来解决这个问题。一如既往地谢谢。

编辑:我假设开始和结束时间非常相似,当它们被减去并舍入时,它们是0。

3 个答案:

答案 0 :(得分:1)

我猜是因为float如果数字太大就不够准确。为什么不像你一样使用long

long start = System.nanoTime();
//Do stuff
long duration = System.nanoTime() - start;
double durationInSeconds = duration / 1000000000.0d;

答案 1 :(得分:0)

看一下字节码。也许编译器正在剥离调用。如果是这种情况,只需创建一个public volatile field并将其分配给方法内部或作为返回值。

致电dead-code elimination。它不是唯一可以执行的优化。

对类文件进行解组并查看以防万一。您可以使用javap执行此操作。

看看[1]和[2]的微观基准建议。

[1] http://www.oracle.com/technetwork/java/hotspotfaq-138619.html#benchmarking_simple

[2] http://shipilev.net/talks/devoxx-Nov2013-benchmarking.pdf

答案 2 :(得分:0)

答案的三个部分。

  1. 您应该从不减去非常接近值的浮点数。你会得到严重的精度损失,到了无用的程度。在这种情况下,减去整数并仅转换为双精度以显示结果。

  2. 从我所看到的代码中,它看起来是瞬间的 - 在微秒范围内或以下 - 并且时间函数不提供该级别的分辨率。这种方式无法获得有用的结果。

  3. 基准时间微妙,复杂且令人困惑(即使它的行为正确!)。请仔细阅读提供的参考资料并做好计划。你想测量什么?你怎么能这样做?您将如何处理结果。

  4. 参考:How do I write a correct micro-benchmark in Java?