System.getCurrentTimeMillis()

时间:2018-02-15 15:42:41

标签: java performance optimization

我正在制作一种概率模拟器,它可以运行一定的时间,也可以运行一定的重复次数。我正在寻求优化它,它目前是多线程的,每个ProbabilityWorker扩展Thread,主程序将自动分配n个线程,其中n是许多线程都可用(例如:在我的Core i3-7100U上,这是4)。

我正在分析这个的性能,我意识到我用来获取结束时间的当前时间的方法会导致很多开销。

对于可以“运行一段时间”的模式,我将new Date个对象作为循环条件的一部分,然后我将其更改为更快System.currentTimeMillis()以尝试并节省时间,但我注意到即使这会导致开销。

我的run函数如下所示:

public void run() {
    if (mode) {
        while (completed < repitions) {
            resultSet[randy.nextInt(o)]++;
            completed++;
        }
    } else {
        while (System.currentTimeMillis() < endTime) {
            resultSet[randy.nextInt(o)]++;
            completed++;
        }
    }
    done = true;
}

mode true如果为了重复而运行,randy是随机的,o是可能的结果数量,endTime是以毫秒为单位的终点,系统时间(可以修改,程序需要几秒钟,endTime由当前时间加secondsInput * 1000计算。)

此外,在同一Core i3-7100U上,这些是我的性能统计数据:

DE-WEY-LAPTOP:/mnt/c/Users/danny/Documents/Programming/Data Structures/Probability$ java Main -n 10000000000

Running 10000000000 repitions of the probability simulator with 2 possible outcomes.
4 threads detected on system; doing 2500000000 repitions per thread.
Done. Gathering results from worker threads...
Done. Printing results...
Outcome 1: 4999997330 out of 10000000000 (49.9999733%)
Outcome 2: 5000002670 out of 10000000000 (50.0000267%)
Time taken: 43.443 seconds (2.301866813986143E8 ops/sec)

DE-WEY-LAPTOP:/mnt/c/Users/danny/Documents/Programming/Data Structures/Probability$ java Main -t 44

Running the probability simulator for 44 seconds using 4 threads.
Done. Gathering results from worker threads...
Done. Printing results...
Outcome 1: 141568074 out of 283130850 (50.000935609807264%)
Outcome 2: 141562776 out of 283130850 (49.999064390192736%)
Time taken: 44 seconds (6434792.045454546 ops/sec)

我的问题是,有没有办法优化System.currentTimeMillis()调用,要么没有它,要么减少需要多少时间?我可以使用另一个更快的通话吗?

1 个答案:

答案 0 :(得分:3)

你应该真正关注System.nanoTime(并坚持下去) - 这是你在JVM AFAIK中获得的最好成绩。除了测量经过时间而没有任何时钟概念的事实,它也是最快的 - 这就是JMH使用它的原因(或者我希望的任何其他理智的微基准)

除了class Uploadimage extends Component { constructor(props) { super(props); this.state = { file: '', images:[], }; this.fileReader = new FileReader(); } setImages = (e) => { e.preventDefault(); let self = this; // unsure if this is needed self.setState({ images: [] }); // empty out current images array const imageFiles = e.target.files; // document.getElementById("image"); // You may want to avoid querying the dom yourself, try and rely on react as much as possible const filesLength = imageFiles.length; // imageFiles.files.length; // const temp = null; for(var i = 0; i < filesLength; i++) { let reader = new FileReader(); let file = imageFiles[i]; reader.onloadend = () => { self.setState({ images: self.state.images.concat(reader.result); }); } reader.readAsDataURL(file); } } render() { let { images } = this.state; return ( <div> <form onSubmit={this._handleSubmit}> <Input id="image" type="file" multiple defaultValue='no file chosen' onChange={this.setImages} /> <Button icon='upload' type="submit" onClick={this._handleSubmit}>Upload Image</Button> </form> {images.map((item,index) => <img src={item} />)} </div> ) } } 返回System.currentTimeMillis精度的事实(并且有些事情比ms更快),两次调用此方法can return a negative value之间的差异。

有两件事要记住,首先是对1ms的每次调用都有性能影响,平均而言(在我的,接近你的CPU和JVM-9){{每次通话1}}

最后一点是System.nanoTime具有纳秒秒精度,但不是纳秒秒精度。这意味着当您致电:

25 ns

两个结果都将返回一个具有纳秒精度的数字,即它们将具有多个数字。

但这个数字不能很准确。那么,根据你的要求准确。由于System.nanoTime返回的值是任意值,因此除非对long start = System.nanoTime(); long end = System.nanoTime(); 进行其他调用,否则无法对其进行比较,因此:

System.nanoTime

/可能不会是纳秒级的准确结果。这个不准确度约为1微秒,在我的笔记本电脑上约为0.2-0.5微秒。

使用System.nanoTime,没有更快或更细粒度的东西。