我想通过查看方法完成所需的时间来进行一些研究以提高我的程序员技能。
但是我不想在我测试的java文件中编写任何代码,因为我有很多方法要测试(对于一些代码我没有编辑代码的权限)所以如果可能的话我只想"观看"方法。
例如:
public void methodZero(){
methodOne();
methodTwo();
}
理想情况下应该打印如下内容:
Time of methodZero = x. Time of methodOne = y. Time of methodTwo = z.
问题:我可以像这样测量时间吗?是否有一些对我来说很重要的信息,比如内存使用?
答案 0 :(得分:4)
单独定时方法通常完全没有意义,一开始你需要统计样本。如果你想获得一个方法的运行时间,你必须考虑很多事情,并尽可能多地为你的时间目标提供上下文。
例如,假设您的方法具有返回值,但您不在基准测试中以任何方式使用它 - 您可能会遇到JVM的“死代码消除”,这会使您的时间毫无意义。 JVM做了许多这样聪明的事情(openjdk.net: Performance techniques used in the Hotspot JVM),所有这些都使得采取有意义的时机变得混乱和复杂。
用于帮助您执行此操作的良好库(具有良好的文档和教程)是JMH。
与实际时间一样重要,但通常与采取有意义的时间相关,是测量算法space and time complexity。这使您可以了解算法在输入数据集大小变化时的增长方式。例如,MethodA
在小输入数组上可能更快,而在输入数组100x更大时效率更低,而MethodB
可能需要相同的时间而不管数组大小。
如果您想了解程序中的哪个位置,您应该开始寻求提高性能,您可以使用分析器(e.g. eclipse.org: An introduction to profiling Java applications)。这将帮助您识别诸如以下内容:高内存使用率,高GC使用率,总方法时间(例如,低方法调用计数但高执行时间,或高呼叫计数以及小但重要的执行时间)。但是,分析器也会影响程序的执行时间。
TL; DR:分析和性能测试很难。通常你并没有真正衡量你认为自己在测量的东西。
答案 1 :(得分:2)
module Evens where
{-@ type Even = {v:Int | v mod 2 = 0} @-}
{-@ square :: Even -> Int @-}
square :: Int -> Int
square n = n * n
-- calling the function:
yup = square 4
-- nope = square 3 -- will not compile if this is uncommented
作为程序员,您应该对算法的复杂性(通常是时间复杂度,但有时您也应该担心空间复杂性)更感兴趣,而不是执行程序所花费的实际时间。 阅读有关分析算法复杂性的here