`

System.nano()详解

 
阅读更多

System.nanoTime只能用于计算时间差,不能用于计算时间的准确度(System.out.println(new Date(System.nanoTime()));这种是绝对错误的)。

Returns the current value of the most precise available system timer, in nanoseconds.

This method can only be used to measure elapsed time and is not related to any other notion of system or wall-clock time. The value returned represents nanoseconds since some fixed but arbitrary time (perhaps in the future, so values may be negative). This method provides nanosecond precision, but not necessarily nanosecond accuracy. No guarantees are made about how frequently values change. Differences in successive calls that span greater than approximately 292 years (263 nanoseconds) will not accurately compute elapsed time due to numerical overflow.

For example, to measure how long some code takes to execute:

1.long startTime = System.nanoTime();   
2.// ... the code being measured ...   
3.long estimatedTime = System.nanoTime() - startTime;

 

2) Java中的System.nano()很慢

 

 System.nano()调用耗时450 nano,超级慢,比new Object()的操作慢100倍。比System.currentMillis()慢20多倍。

经一群无聊好事者查证,System.nanoTime()在linux下的实现,最终调用clock_gettime系统函数。

100万次调用耗时,java语言中System.nanoTime()和C语言中的clock_gettime()调用时间基本一致,所以System.nanoTime()慢的原因就是系统调用clock_gettime。

无聊好事者请注意,自行测试System.nanoTime()性能时,要这样写:

 

1.for (int i = 0; i < 1000 * 1000; ++i) {   
2.    long v = System.nanoTime();   
3.}  

 

而不能这样写:

 

1.for (int i = 0; i < 1000 * 1000; ++i) {   
2.    System.nanoTime();   
3.} 

 

上面梁总写法区别:

 

1.public class NanoTimeTest {   
2.    public static void main(String [] args) {   
3.        test1();   
4.        test2();   
5.    }   
6.  
7.    static void test1() {   
8.        long time = System.currentTimeMillis();   
9.        for(int i=0; i < 1000 * 1000; ++i) {   
10.            System.nanoTime();   
11.        }   
12.        System.out.println("test1:" + (System.currentTimeMillis() - time));   
13.    }   
14.  
15.    static void test2() {   
16.        long time = System.currentTimeMillis();   
17.        for(int i=0; i < 1000 * 1000; ++i) {   
18.            long v = System.nanoTime();   
19.        }   
20.        System.out.println("test2:" + (System.currentTimeMillis() - time));   
21.    }   
22.}  

 

F:\Java2>java -server NanoTimeTest
test1:500
test2:500

F:\Java2>java -client NanoTimeTest
test1:16
test2:484 

 

3)

Java5+

摩尔定律是一种众所周知的现象,即计算机中的晶体管数量和它的处理速度随时间呈指数规律增长。作为仙童半导体公司(Fairchild Semiconductor)的研发领导人,戈登•摩尔于1965年提出了这一伟大发现。迄今为止,它仍有效。
与Java首次出现的时候相比,当前计算机的速度要快得多,对于很多应用程序而言以毫秒计时已不再能够满足要求。你可能使用过java.lang.System类,利用currentTimeMillis方法来获得一个方法调用或一段代码的定时信息。此方法可以用来度量执行某操作所花费的时间。但是,在运算速度更快的计算机上操作花费的时间可能远小于1毫秒,于是可以在一个for循环中执行此操作上百次或上千次,然后除以循环次数来计算此操作的单位时间。考虑下面的示例:

 

long startTime = System.currentTimeMillis();
for (int i=0; i<1000; i++) {
performOperation(); // something we want to measure
}
long endTime = System.currentTimeMillis();
long totalTimeInMillis = endTime - startTime;
// because the count was 1000, it's easy to get the unit time
long unitTimeInMicros = totalTimeInMillis; 

 

这种一种很简单的运算,因为使用了for循环1000次。但是如果要度量亚微秒该如何实现呢?

 

for(int i=0; i<1000000; i++) { performOperation(); } 

 

如果从人类的角度来看,可怜的for循环将不得不不厌其烦地百万次的频繁循环!此外,只有在重复执行操作没有副作用的情况下使用for循环来计算时间才是有用的。如果操作是调用java.util.Collections.sort方法,那么将很难计算出排序过程花费的时间。在Java 5中,System类有一个新的nanoTime方法,它能返回一个纳秒精度的计数器。尽管不能将它用于度量绝对时间,但是它能够很好地度量时间差别。

 

List myList = initializeList();  // initialize the List somehow
long startTime = System.nanoTime();
Collections.sort(myList);         // measuring the sort time
long endTime = System.nanoTime();
long differenceInNanoseconds = endTime - startTime; 

 

 

遗憾的是,运行上面的代码时无法保证实际上获得的是纳秒级的度量。但是使用更快的机器和良好的JRE实现,对于测试目的而言它是一种有用的度量方法。可以在JDK 5文档中找到更多有关此方法的信息。鉴于操作系统特性、机器处理速度和系统负载的不同,得到的由nanoTime方法返回的值可能会有很大的变化。随着时间的推移此问题应该会有所改善,摩尔定律基本上能保证这一点。

参考资料:

想要了解摩尔的原始论文,请参看Gordon E. Moore, Cramming More Components onto Integrated Circuits, Electronics, Vol. 38, No. 8 (April 19, 1965)。此外,还可以在网上获得该论文,参看本书的网站http:// wickedcooljava.com以获得URL。

分享到:
评论

相关推荐

    最-NANO_STM32F103开发指南_寄存器版本_V1.0.pdf

    1. 开发板介绍:文档中提到了正点原子NANO STM32F103开发板,这是针对STM32F1系列微控制器的一个开发平台。STM32系列是由STMicroelectronics(意法半导体)公司生产的基于ARM Cortex-M3内核的32位微控制器。 2. ...

    The-Linux-System-dsi.unifi.it完整.pptx

    Linux系统详解 Linux系统是基于UNIX操作系统的概念发展起来的,它主要由三个核心部分组成:标准实用程序、标准库和内核。这些组件共同构成了一个功能强大的操作系统,被广泛应用于服务器、桌面环境以及嵌入式设备中...

    MAC 终端使用方法

    1. nano编辑器:可以使用nano命令来编辑文件,例如,想编辑Natit.kext文件,可以使用nano /System/Library/Extensions/Natit.kext/Info.plist命令。 2. vi编辑器:可以使用vi命令来编辑文件,例如,想编辑Natit.kext...

    安卓厨房安装与使用.docx

    **添加Nano文本编辑器**:提供简单易用的文本编辑工具。 15. **添加Bash命令行**:增加Linux命令行功能。 16. **App2SD**:支持应用程序移动到SD卡。 17. **/etc/init.d脚本支持**:借助busybox实现自启动脚本。...

    大数据学习路径.docx

    - **文本编辑器**:熟练使用`vim`或`nano`等编辑器。 ##### 2. 分布式集群技术 - **概念理解**:了解负载均衡、高可用性等集群技术的基本原理。 - **实际操作**:能够搭建并维护高并发、高可用的服务器集群。 - **...

    mac终端命令[参考].pdf

    Mac 终端命令详解 在本节中,我们将介绍 Mac 终端命令的基本使用和操作方法。Mac 终端命令是基于 Unix 文件系统的,因此我们需要了解 Unix 文件系统的基本概念。 文件系统 Mac 终端命令使用 Unix 文件系统,所有...

    jdk-8u311-linux-x64.tar.gz

    《JDK8在Linux系统中的安装与配置详解》 JDK(Java Development Kit)是Oracle公司提供的用于开发和运行Java应用程序的工具集合,是Java编程的基础。本篇文章将详细阐述如何在Linux系统中安装JDK8,具体以"jdk-8u...

    nexus-3.27.0-03-unix.tar.gz

    sudo nano /etc/systemd/system/nexus.service ``` 在编辑器中输入服务配置,然后保存并退出。 4. **启动Nexus**:启动Nexus服务,并检查状态。 ```bash sudo systemctl start nexus sudo systemctl status nexus `...

    Elasticsearch 的下载、配置和使用案例的详细步骤.pdf

    ### Elasticsearch 的下载、配置与使用案例详解 #### 一、Elasticsearch 简介 Elasticsearch 是一款基于 Apache Lucene 构建的开源分布式搜索引擎。它支持高并发访问和实时数据分析,广泛应用于日志分析、全文检索...

    jdk7-ubuntu16.rar

    《Ubuntu 16.04上安装与配置OpenJDK 7详解》 在信息技术领域,Java开发工具包(Java Development Kit,简称JDK)是Java编程语言开发环境的核心组件,它包含了Java编译器、Java运行时环境以及其他必要的工具。...

    ubuntu 10.04 TFTP和NFS配置详解

    在Ubuntu 10.04操作系统中,TFTP(Trivial File Transfer Protocol)和NFS(Network File System)是两种常用的网络文件传输和共享服务。本文将深入探讨这两种服务的配置过程,确保它们在实际环境中能够正常工作。 ...

    mac终端命令

    ### Mac终端命令详解 #### 一、Mac OS X 文件系统概览 - **根目录**:`/` 是Mac OS X文件系统的起点,所有的文件和目录都从这里挂载下来。与Windows不同,Mac没有盘符的概念。 - **驱动器位置**:驱动器通常被挂载...

    mysql-5.7.21-linux-glibc2.12-x86_64.tar.gz 百.度.网.盘地址及密码

    sudo nano /etc/systemd/system/mysqld.service ``` 内容如下: ``` [Unit] Description=MySQL Server After=network.target [Service] User=mysql ExecStart=/usr/local/mysql/bin/mysqld ExecReload=/bin/kill -...

    MAC OS X系统终端的常用命令

    例如,`nano /System/Library/Extensions/Natit.kext/Info.plist`将打开指定文件进行编辑。 - **`vi`**:另一个常用的文本编辑器,功能强大但学习曲线较陡峭。 - **`sh`**:Shell脚本解释器,用于执行脚本文件。例如...

    nginx-1.0.1.tar.gz

    sudo nano /etc/systemd/system/nginx.service ``` 在文件中添加如下内容: ```ini [Unit] Description=Nginx HTTP Server After=network.target [Service] User=root Group=nobody ExecStart=/usr/...

    linu下jdk8

    【标题】:“Linux环境下安装与配置JDK8详解” 【正文】: 在Linux系统中,Java Development Kit(JDK)是开发和运行Java应用程序的基础。JDK8是Oracle公司发布的一个重要版本,它引入了许多新特性,如Lambda表达式...

    redis安装配置.docx

    sudo nano /etc/systemd/system/redis.service ``` - 编辑服务文件,内容如下: ```ini [Unit] Description=Redis in-memory data store After=network.target [Service] User=redis ExecStart=/usr/...

    Ubuntu下的 Java配置

    ### Ubuntu 下的 Java 配置详解 #### 一、引言 随着计算机技术的发展与普及,Linux 操作系统因其开放性和灵活性,在服务器领域占据了一席之地。对于学习计算机的同学而言,掌握 Linux 平台下的各种编程语言尤为重要...

    linux下jdk的安装步骤

    ### Linux下JDK的安装与配置详解 #### 一、前言 在Linux环境下搭建Java开发环境是一项基本技能,尤其对于从事Java应用开发的技术人员来说更是必不可少。本文将详细介绍如何在Linux系统上安装并配置JDK(Java ...

Global site tag (gtag.js) - Google Analytics