网站首页 > 技术文章 正文
计算耗时的方法
常见的计算一段代码的耗时情况都是计算开始时间点的时间戳,然后在结束的时候用当前时间戳减去之前记录好的,例如:
java复制代码Long starTime = System.currentTimeMillis();
// ....
Long runTime = System.currentTimeMillis() - starTime;
但如果我说这个方式其实是错的,不准确的,是不是有点颠覆你的认知。
先把结论放这里:
System.currentTimeMillis用的是墙上时钟,墙上时钟在计算时间间隔有可能会有误差,计算时间间隔应该用单调时钟System.nanoTime。
短时间方法内测一下倒是也没关系,如果是长作业任务测量执行时间,最好还是用单调时钟。
依赖时钟的方式
首先将一下日常开发中,我们 应用程序会以各种方式依赖时钟,大致类别有:时间间隔和时间点。
时间间隔
- 某个请求是否超时
- 某项服务99%的响应时间是多少
- QPS、TPS
时间点
- 文章定时发送、定时推送消息
- 缓存条目何时过期
时钟种类
单调时钟 墙上时钟(钟表时间)
墙上时钟
根据某个日历(参照时间)返回当前的日期与时间。
Java中的System.currenTimeMillis就是典型的墙上时钟。
他会返回自1970年1月1日以来的秒数和毫秒数(不含闰秒)。
时钟回拨:
如果本地时钟远远快于NTP服务器,强制重制后会跳回到先前的某个时间点
这种跳跃是忽略闰秒的。所以墙上时钟不适合用来测量时间间隔。
闰秒:由于地球的不均匀自转和长期变慢性。会使世界时和原子时之间相差正负0.9秒。
但出现这种情况时,就要把世界时往前或者往后拨动1秒。
就有可能会出现那一分钟少了一秒或者多了一秒:9:46:59秒 9:46:60秒。
单调时钟
单调时钟更适合测量时间段(时间间隔),例如超时或者服务的响应时间。
Java中的System.nanoTime。返回的就是单调时钟。
单调时钟,意味着他永远都是向前,不会出现墙上时钟回拨的现象。
在开发中,我们肯定会写过在某个动作开始前用System.currenTimeMillis获取时间戳,然后在结束的时间再获取一次,然后两者相见。
但其实这种最好是用单调时间来做,因为墙上时钟会有时钟回拨的问题,不适测量时间点。
单调时钟参考的可能是电脑启动以后经历的纳秒数或者是其他。因此比较不同节点上的单调时钟差值毫无意义。
时钟摆动:
如果本地的单调时钟快于或慢于NTP,NTP会控制本地石英的振动频率(也叫摆动)。
总结
- 时钟分为墙上时钟和单调时钟。
- 墙上时钟:Sytem.currenTimeMillis,单调时钟:System.nanoTime。
- 墙上时钟出现时钟时钟回拨时会忽略闰秒,所以不适合用于测量时间间隔。
下一篇讲讲分布式系统中的2个最不可靠的组件,不可靠时钟,图灵机得主Lamport老爷子有一篇关于时钟的的论文 《Time, Clocks, and the Ordering of Events in a Distributed System》,这篇论文也是在分布式领域被引用最多的。
作者:Ashleejy
链接:https://juejin.cn/post/7240374267697791034
猜你喜欢
- 2024-09-21 Java并发编程:LongAdder | LongAccumulator 对比测试
- 2024-09-21 「Java技巧」优雅的统计程序的执行时间,别再用System.cur
- 2024-09-21 Flink SQL 知其所以然(九)| SQL 的时间语义
- 2024-09-21 ArrayList插入1000w条数据之后,我怀疑了jvm...
- 2024-09-21 《Java实战之内存模型》详解篇(java内存模型happens before)
- 2024-09-21 比反射更快!使用ASM获取class信息(ClassReader)
- 2024-09-21 了解Java线程优先级,更要知道对应操作系统的优先级,不然会踩坑
- 2024-09-21 让大学生写的一个计算时间的方法,有人看得出来是在做什么吗?这
- 2024-09-21 Java基础——Java多线程(Lock接口详解)
- 2024-09-21 JVM性能调优监控工具jps、jstack、jmap、jhat、jstat使用详解
- 1514℃桌面软件开发新体验!用 Blazor Hybrid 打造简洁高效的视频处理工具
- 569℃Dify工具使用全场景:dify-sandbox沙盒的原理(源码篇·第2期)
- 510℃MySQL service启动脚本浅析(r12笔记第59天)
- 486℃服务器异常重启,导致mysql启动失败,问题解决过程记录
- 485℃启用MySQL查询缓存(mysql8.0查询缓存)
- 467℃「赵强老师」MySQL的闪回(赵强iso是哪个大学毕业的)
- 446℃mysql服务怎么启动和关闭?(mysql服务怎么启动和关闭)
- 444℃MySQL server PID file could not be found!失败
- 最近发表
- 标签列表
-
- c++中::是什么意思 (83)
- 标签用于 (65)
- 主键只能有一个吗 (66)
- c#console.writeline不显示 (75)
- pythoncase语句 (81)
- es6includes (73)
- windowsscripthost (67)
- apt-getinstall-y (86)
- node_modules怎么生成 (76)
- c++int转char (75)
- static函数和普通函数 (76)
- el-date-picker开始日期早于结束日期 (70)
- js判断是否是json字符串 (67)
- checkout-b (67)
- c语言min函数头文件 (68)
- asynccallback (71)
- localstorage.removeitem (74)
- vector线程安全吗 (70)
- & (66)
- java (73)
- js数组插入 (83)
- mac安装java (72)
- eacces (67)
- 查看mysql是否启动 (70)
- 无效的列索引 (74)