乐趣区

关于java:SystemcurrentTimeMillis-和-SystemnanoTime-哪个更快别用错了

作者:捏造的信奉 \
起源:https://segmentfault.com/a/11…

Java 有两个取工夫戳的办法:System.currentTimeMillis()System.nanoTime(),它们的应用场景是有区别的,以后网上一些文章对于这两个办法的性能探讨存在一些全面的形容,本文心愿能给出一个简略的最终答案。

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

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

Windows:

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

所以如果你的生产环境是 Windows,请尽可能防止应用 System.nanoTime()

Linux:

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

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

现在的云主机次要有 Xen 和 KVM 两种实现形式,网上有文章发现它们在取零碎工夫方面存在性能差别。

当你的虚拟机用的是 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。

近期热文举荐:

1.1,000+ 道 Java 面试题及答案整顿 (2022 最新版)

2. 劲爆!Java 协程要来了。。。

3.Spring Boot 2.x 教程,太全了!

4. 别再写满屏的爆爆爆炸类了,试试装璜器模式,这才是优雅的形式!!

5.《Java 开发手册(嵩山版)》最新公布,速速下载!

感觉不错,别忘了顺手点赞 + 转发哦!

退出移动版