ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

关于Java的取时间方法的争论

2022-01-13 13:30:13  阅读:179  来源: 互联网

标签:COUNT 争论 Java System currentTimeMillis 关于 nanoTime LOOP out


Java有两个取时间的方法: System.currentTimeMillis() 和 System.nanoTime() ,它们的使用场景是有区别的,当前网上一些文章对于这两个方法的性能问题存在一些片面的描述,本文希望能给出一个简单的最终答案。

System.currentTimeMillis() 存在性能问题?

答案是否定的。这两个方法性能差异取决于操作系统。

Windows:

在 Windows 下, System.currentTimeMillis() 比 System.nanoTime() 要快很多,这是因为 Windows 系统为前者提供的只是一个缓存变量,而后者则是实时的去硬件底层获取计数。

因此如果你的生产环境是 Windows,请务必不要使用 System.nanoTime() !

Linux:

在 Linux 下,两者的执行耗时相差不大,不论是单线程还是多线程。

不同的虚拟机实现会带来性能差异

如今的云主机主要有 Xen 和 KVM 两种实现方式,网上有文章发现它们在取系统时间方面存在性能差异。

文章地址: https://www.javaadvent.com/20...

当你的虚拟机用的是 Xen 时,取时间的耗时会是 KVM 的十倍以上。不过上文也提供了遇到此类问题该如何解决的方案。

需要写一个专门的类来提升 System.currentTimeMillis() 性能吗?

不需要。那属于画蛇添足。

我的测试代码

我的测试代码如下,没有任何依赖,可以直接用 javac 编译然后运行。读者有兴趣可以试试:

import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;

public class TimePerformance {

    public static final int LOOP_COUNT = 9999999;
    public static final int THREAD_COUNT = 30;

    public static void main(String[] args) {

        Runnable millisTest = () -> {

            long start = System.currentTimeMillis();
            for (int i = 0; i < LOOP_COUNT; i++) {
                System.currentTimeMillis();
            }
            long end = System.currentTimeMillis();

            System.out.printf("%s : %f ns per call\n",
                    Thread.currentThread().getName(), ((double)end - start) * 1000000 / LOOP_COUNT);
        };

        Runnable nanoTest = () -> {

            long start = System.currentTimeMillis();
            for (int i = 0; i < LOOP_COUNT; i++) {
                System.nanoTime();
            }
            long end = System.currentTimeMillis();

            System.out.printf("%s : %f ns per call\n",
                    Thread.currentThread().getName(), ((double)end - start) * 1000000 / LOOP_COUNT);
        };

        Consumer<Runnable> testing = test -> {
            System.out.println("Single thread test:");
            test.run();

            System.out.println(THREAD_COUNT + " threads test:");
            List<Thread> threads = new ArrayList<>();
            for (int i = 0; i < THREAD_COUNT; i++) {
                Thread t = new Thread(test);
                t.start();
                threads.add(t);
            }
            // Wait for all threads to finish
            threads.forEach(thread -> {
                try {
                    thread.join();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
        };

        System.out.println(" Test System.nanoTime()");
        testing.accept(nanoTest);
        System.out.println(" Test System.currentTimeMillis()");
        testing.accept(millisTest);
    }
}

因为我用的是 Windows,所以执行输出当中 System.nanoTime() 明显非常慢。具体输出内容我就不放出来了,因为不具有参考价值,大多数生产环境用的是 Linux。

标签:COUNT,争论,Java,System,currentTimeMillis,关于,nanoTime,LOOP,out
来源: https://blog.csdn.net/zybb166/article/details/122471822

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有