代码之家  ›  专栏  ›  技术社区  ›  Lydon Ch

Java性能测量

  •  10
  • Lydon Ch  · 技术社区  · 14 年前

    我正在对我的类进行一些Java性能比较,并且想知道是否有某种Java性能框架使编写性能测量代码更容易?

    也就是说,我现在正在做的是,与使用原子整数作为我的“同步器”相比,使用pseudorandomunigsynch.nextint()中的“synchronized”方法来测量它有什么效果。

    所以我试图测量使用3个线程访问一个同步方法循环(比如10000次)生成随机整数需要多长时间。

    我相信有更好的方法可以做到这一点。你能启发我吗?:)

    public static void main( String [] args ) throws InterruptedException, ExecutionException {
        PseudoRandomUsingSynch rand1 = new PseudoRandomUsingSynch((int)System.currentTimeMillis());
        int n = 3;
        ExecutorService execService = Executors.newFixedThreadPool(n);
    
        long timeBefore = System.currentTimeMillis();
        for(int idx=0; idx<100000; ++idx) {
            Future<Integer> future = execService.submit(rand1);
            Future<Integer> future1 = execService.submit(rand1);
            Future<Integer> future2 = execService.submit(rand1);
    
            int random1 = future.get();
            int random2 = future1.get();
            int random3 = future2.get();
    
        }
        long timeAfter = System.currentTimeMillis();
        long elapsed = timeAfter - timeBefore;
        out.println("elapsed:" + elapsed);
    }
    

    班级

    public class PseudoRandomUsingSynch implements Callable<Integer> {
    private int seed;
    
    public PseudoRandomUsingSynch(int s) { seed = s; }
    
    public synchronized int nextInt(int n) {
        byte [] s = DonsUtil.intToByteArray(seed);
        SecureRandom secureRandom = new SecureRandom(s);
        return ( secureRandom.nextInt() % n );
    }
    
    @Override
    public Integer call() throws Exception {
        return nextInt((int)System.currentTimeMillis());
    }
    }
    

    当做

    6 回复  |  直到 6 年前
        1
  •  12
  •   Cowan    14 年前

    忽略了微基准是否对你有用的问题(斯蒂芬C的观点是 非常 有效),我会指出:

    首先,不要听那些说“没那么难”的人说。是的,使用JIT编译在虚拟机上微标记是困难的。实际上很难从微基准中得到有意义和有用的数据,任何声称不难的人要么是超级天才,要么就是做错了。:)

    其次,是的,有一些这样的框架。值得一看的是 Caliper ,作者是谷歌的凯文·布尔里利翁和杰西·威尔逊。从一些早期的观察来看,它确实令人印象深刻。

        2
  •  8
  •   Stephen C    9 年前

    更多的微观基准建议-微观基准很少告诉你你真正需要知道的…这就是实际应用程序运行的速度。

    在你的情况下,我想你是想知道 您的应用程序 使用原子对象比使用同步对象性能更好…反之亦然。真正的答案是 这很可能取决于微观基准无法衡量的因素。 . 例如,争用的概率、持有锁的时间、线程和处理器的数量以及使原子更新成为可行解决方案所需的额外算法工作量。

    编辑 -回答这个问题。

    那么,有没有一种方法可以测量所有这些争用概率、锁保持时间等?

    理论上是的。一旦实现了整个应用程序,就可以对其进行检测以测量这些内容。但这也不能给出你的答案,因为没有一个预测模型,你可以把这些数字插入其中给出答案。此外,到那时您已经实现了应用程序。

    但我的观点并不是通过测量这些因素来预测绩效。(没有!)相反,这是一个微观基准 没有 允许您预测性能 任何一个 .

    实际上,最佳方法是根据您的直觉实现应用程序,然后使用概要分析作为确定实际性能问题所在的基础。

        3
  •  4
  •   jediz 114326671    6 年前

    这些人设计了一个好的JVM度量方法,这样你就不会用虚假的数字来愚弄自己,然后将它作为一个python脚本发布,这样你就可以重用他们的聪明了。-

    Statistically Rigorous Java Performance Evaluation (pdf paper)

        4
  •  3
  •   Tom Hawtin - tackline    14 年前

    您可能希望将循环移动到任务中。实际上,您只需启动所有线程,几乎立即返回单线程。

    通常的微生物标记建议:允许一些热身。和平均值一样,偏差也很有趣。使用 System.nanoTime 而不是 System.currentTimeMillis .

    这个问题的具体问题是线程的竞争程度。对于大量争用线程,CAS循环可能会执行浪费的工作。创建 SecureRandom 可能很贵,也可能很贵 系统当前时间毫秒 在较小程度上。我相信 安全随机 如果使用正确,应该已经是线程安全的。

        5
  •  3
  •   Radim Vansa    9 年前

    OpenJDK开发了一个名为JMH的基准测试工具:

    http://openjdk.java.net/projects/code-tools/jmh/

    这提供了一个非常容易设置的框架,并且有几个示例显示了如何使用它。

    http://hg.openjdk.java.net/code-tools/jmh/file/tip/jmh-samples/src/main/java/org/openjdk/jmh/samples/

    没有什么可以阻止您错误地编写基准,但它们在消除不明显的错误(例如线程间的错误共享、防止死码消除等)方面做得很好。

        6
  •  1
  •   BalusC    14 年前

    简而言之,你是在寻找一个“Java单元性能测试工具”?

    使用 JUnitPerf .

    更新: 对于这种情况,还不清楚:它还支持并发(多线程)测试。以下是上述链接“负载测试”一章的摘录,其中包括一个代码示例:

    例如,要创建的负载测试 每个用户10个并发用户 运行 示例testcase.testonesecondresponse()) 20次迭代的方法,用1 添加之间的第二个延迟 用户,使用:

    int users = 10;
    int iterations = 20;
    Timer timer = new ConstantTimer(1000);
    Test testCase = new ExampleTestCase("testOneSecondResponse");
    Test repeatedTest = new RepeatedTest(testCase, iterations);
    Test loadTest = new LoadTest(repeatedTest, users, timer);