Java 中高精度计时? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Richard14
V2EX    Java

Java 中高精度计时?

  •  
  •   Richard14 2022 年 7 月 19 日 3879 次点击
    这是一个创建于 1331 天前的主题,其中的信息可能已经有所发展或是发生改变。

    根据廖雪峰教学博客,java 中处理日期 /时间问题,如无特殊必要应优先采用较新的 java.time 模块。

    一个疑问是,写码时常见需求是获取两点之间执行时间。按照该博客说明,精度最高的应该是 Instant 类,所以计算两点间代码行时间应该可以使用下列代码:

    public class Main { public class void Main() { var start = Instant.now(); // ... run some code System.out.println("done"); var end = Instant.now(); System.out.println(instantToDouble(end) - instantToDouble(start)); } protected static double instantToDouble(Instant instant) { return instant.getEpochSecond() + instant.getNano() / 1e9; } } 

    实际得到结果两点间差值是 0.0 ,两个 instant 获得的时间完全一致,让人疑惑因为 instant 理论上是纳秒级精度,而两点之间执行了 sout 代码,sout 根据廖旭峰的说明是一个同步 IO ,所以理论上上述代码不应该输出 0 ,导致它输出 0 的原因是什么呢? instant 精度不够吗,或者 io 流的问题?


    另外再顺便问下 instant 是什么设计,导入是通过 import java.time.*导入的,正常来说创建对象应该是用类似 var instant = new Instant().now();这种感觉的句子,为什么 instant 可以直接 var instant = Instant.now()?

    21 条回复    2022-07-21 12:29:01 +08:00
    zzl22100048
        1
    zzl22100048  
       2022 年 7 月 19 日 via iPhone
    计算时间差用 nanotime
    Instant.now()是静态工厂方法,是构造函数的语义化封装
    Aloento
        2
    Aloento  
       2022 年 7 月 19 日
    每个平台都有一个最小时间精度,Windows 的间隔最大,Java 自己也有损
    Procumbens
        3
    Procumbens  
       2022 年 7 月 19 日
    不需要自己定义一个 instantToDouble 。要比较 start 和 end 就

    Duration timeElapsed = Duration.between(start, end);
    System.out.println(timeElapsed.toNanos()); // 或者精确到毫秒: timeElapsed.toMillis()
    FYFX
        4
    FYFX  
       2022 年 7 月 19 日
    Instant.now() 是静态工厂方法,要想深入了解的话可以看 effective java
    sprit
        5
    sprit  
       2022 年 7 月 19 日
    Spring StopWatch
    Richard14
        6
    Richard14  
    OP
       2022 年 7 月 19 日
    @Procumbens 最佳实践学习一个,不过我代码里两个 instance 时间一致可能是什么导致的?同步 IO 都很费时啊
        7
    LeegoYih  
       2022 年 7 月 19 日
    1 纳秒时间,光都只能走 0.299792458 米,区区 Java 何德何能
    senninha
        8
    senninha  
       2022 年 7 月 19 日
    这是浮点数丢精度了。
    senninha
        9
    senninha  
       2022 年 7 月 19 日
    @senninha 看了一下实现,SystemClock 本来就是毫秒精度。。
    ```
    @Override
    public Instant instant() {
    return Instant.ofEpochMilli(millis());
    }
    ```
    Richard14
        10
    Richard14  
    OP
       2022 年 7 月 19 日
    @zzl22100048 在后面设计模式的章节里查了一下工厂方法。。似乎就是一个类的静态方法返回新的实例。。所以就变成了

    类.静态方法() -> return new Object() 类似这样的。。。。
    Mithril
        11
    Mithril  
       2022 年 7 月 19 日   2
    “纳秒级精度”不代表它有“纳秒级准确度”。
    你是不可能在一个只有毫秒级时钟的系统上,获取准确的纳秒级时间的。
    更别说还是非实时系统了。
    pannanxu
        12
    pannanxu  
       2022 年 7 月 19 日
    guava 秒表:

    ```java
    Stopwatch started = Stopwatch.createStarted();
    Thread.sleep(1000);
    long s = started.stop().elapsed(TimeUnit.MILLISECONDS);
    ```
    wowo243
        13
    wowo243  
       2022 年 7 月 19 日
    试试 StopWatch
    BBCCBB
        14
    BBCBB  
       2022 年 7 月 19 日
    统计耗时用 System.nanoTime, 其他的基本都是 System.currentTimeMillis 的封装. nanoTime 性能消耗比 currentTimeMillis 小的多, 但 nanoTime 不能拿来获取 Unix time, 基本智能用来统计耗时.
    tairan2006
        15
    tairan2006  
       2022 年 7 月 19 日
    纳秒精度属实想多了
    aguesuka
        16
    aguesuka  
       2022 年 7 月 19 日
    windows 是 0, 而 linux 有值, 尽管用 double 表示 96 有效数字然后只关注最后几位很离谱, 而且是 [软工类工作,面试考察底层知识是否合理](v2ex.com/t/865329) 的楼主写的.
    newmlp
        17
    newmlp  
       2022 年 7 月 19 日
    java 是不可能,c/c++还是可以的
    murmur
        18
    murmur  
       2022 年 7 月 19 日
    高精度计时你需要 fpga

    c++也不行

    这玩意必须硬件时钟
    NoKey
        19
    NoKey  
       2022 年 7 月 19 日
    java 这个层面,毫秒已经足够了
    newmlp
        20
    newmlp  
       2022 年 7 月 19 日
    @murmur rdtsc 了解一下
    zjp
        21
    zjp  
       2022 年 7 月 21 日 via Android
    System.nanoTime 的精度可以参考这里
    https://shipilev.net/blog/2014/nanotrusting-nanotime/
    Instant 是基于毫秒的就算了...
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5643 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 29ms UTC 07:17 PVG 15:17 LAX 00:17 JFK 03:17
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86