[英]What is the point of Apache Lang3 StopWatch.split()?
我目前正在评估 Apache 秒表和番石榴的秒表之间的实现,前者的拆分功能让我很感兴趣,但我很难理解它到底做了什么,以及它有什么价值。
split() 手表在后台继续运行时获取时间。 unsplit() 将删除拆分的效果。 此时,这三个选项再次可用。
我发现了一些例子,比如this ,它提供的很少,因为它看起来 split 只是累积的。 该页面说该方法用于“分割时间”,我根据该方法得出了同样多的结论,但该页面没有提及这实际上意味着什么。 甚至看起来这个例子是完全错误的,因为文档建议你应该在再次unsplit
之前取消split
。
我最初认为它适用于以下用例:
StopWatch stopwatch = StopWatch.createStarted();
do something for 5 seconds
stopwatch.split();
do something for 10 seconds
stopwatch.stop();
System.out.println(stopwatch.getTime());
System.out.println(stopwatch.getSplitTime());
我认为秒表总时间读作 15 秒,秒表分割时间读作 10 或 5 秒,但似乎这两种方法 output 都是 15 秒。
接下来,我认为拆分值可能是您可以采用的增量,然后从总计时器中删除,例如:
StopWatch stopwatch = StopWatch.createStarted();
do something for 5 seconds
stopwatch.split();
do something for 10 seconds
stopwatch.unsplit();
stopwatch.stop();
System.out.println(stopwatch.getTime());
// System.out.println(stopwatch.getSplitTime()); errors because of unsplit
我的想法是拆分时间为 10 秒,当从主计时器未拆分时,主计时器将读取为 5 秒......但这似乎与suspend()
调用没有什么不同......我也试过这个,而且时间对我来说还是一样的。
我在这里遗漏了什么,还是我对这应该做的事情的解释都是错误的?
这是getSplitTime()
的源代码(它在内部调用另一个 function ):
public long getSplitNanoTime() {
if (this.splitState != SplitState.SPLIT) {
throw new IllegalStateException("Stopwatch must be split to get the split time. ");
}
return this.stopTime - this.startTime;
}
所以它会返回stopTime-startTime
。 当心stopTime
。 是骗子让你困惑。
这是stop()
的代码:
public void stop() {
if (this.runningState != State.RUNNING && this.runningState != State.SUSPENDED) {
throw new IllegalStateException("Stopwatch is not running. ");
}
if (this.runningState == State.RUNNING)
{
//is this the same stopTime getSplitTime uses? yep, it is
this.stopTime = System.nanoTime();
}
this.runningState = State.STOPPED;
}
那会发生什么?
调用stop()
会更新stopTime
变量并使秒表“忘记”上次拆分的时间。
split()
和stop()
都修改了相同的变量stopTime
,当您在进程结束时调用stop()
时,该变量会被覆盖。
尽管共享同一个变量可能看起来很奇怪,但它确实很有意义,因为StopWatch
的splittedTime
永远不应大于总经过时间。 所以这是一个关于StopWatch
中执行的功能顺序的游戏。
这是split()
的代码,以便看到这两种方法都使用stopTime
:
public void split() {
if (this.runningState != State.RUNNING) {
throw new IllegalStateException("Stopwatch is not running. ");
}
this.stopTime = System.nanoTime(); // you again little f..
this.splitState = SplitState.SPLIT;
}
这就是为什么这个可爱的 Apache 骗子会在 splittedTime 上显示 15 秒:因为stop()
更新了stopTime
变量getSplitTime()
将用于返回其值。 (第一个代码片段)
请注意split()
function 的简单性(这也几乎没有回答 OP 的问题)。 它负责:
StopWatch
是否正在运行。stopTime
。splitState
设置为SPLIT
。 TLDR lol
在停止StopWatch
之前调用getSplitTime()
应该会显示所需的值:
stopTime
不会被stop()
更新。split()
和startTime
之间经过的时间。一些例子:(是的,周六晚上编辑,因为我需要社交生活)
StopWatch stopwatch = StopWatch.createStarted();
do something for 5 seconds
stopwatch.split(); //stopTime is updated [by split()]
System.out.println(stopwatch.getSplitTime()); // will show 5 seconds
do something for 10 seconds
System.out.println(stopwatch.getSplitTime()); // will also show 5 seconds
stopwatch.stop(); //stopTime is updated again [by stop()]
System.out.println(stopwatch.getTime()); // 15s
System.out.println(stopwatch.getSplitTime()); // 15s
另一个:
StopWatch stopwatch = StopWatch.createStarted();
do something for 5 seconds
stopwatch.split();
System.out.println(stopwatch.getSplitTime()); // 5s
do something for 10 seconds
stopwatch.split();
System.out.println(stopwatch.getSplitTime()); // 15s
do something for 1 second
stopwatch.stop();
System.out.println(stopwatch.getTime()); // 16s
最后一个。 用sleeps
来嘲笑时间,只是为了好玩,你知道的。 我太无聊了,我真的进口了 apache jar 以便在本地进行测试:
StopWatch stopwatch = StopWatch.createStarted();
Thread.sleep(5000);
stopwatch.split();
System.out.println(stopwatch.getSplitTime()); // 5s
Thread.sleep(10000);
stopwatch.split();
System.out.println(stopwatch.getSplitTime()); // 15s
stopwatch.reset(); // allows the stopWatch to be started again
stopwatch.start(); // updates startTime
Thread.sleep(2000);
stopwatch.split();
System.out.println(stopwatch.getSplitTime()); // 2s
Thread.sleep(1000);
stopwatch.stop();
System.out.println(stopwatch.getTime()); // 3s
System.out.println(stopwatch.getSplitTime()); // 3s
//it was so fun putting the sleeps
请注意,在停止的Watch
上调用getSplitTime()
不会引发任何异常,因为该方法只会检查splitState
是否为SPLIT
。
混淆可能是由以下两个事实引起的:
stop()
而不管SplitState
,使您的最后一个split()
在您不知道的情况下徒劳无功。 徒劳的,我喜欢这个词。 不得不以某种方式将其包含在我的答案中。 徒劳的splittedTime
(如果它仍处于SPLIT
状态),它实际上只会返回上次start()
和停止时间之间的总经过时间。 (小骗子) 在这种情况下,秒表同时停止和拆分, getTime()
和getSplitTime()
在stop()
之后调用时将始终显示相同的值。
[个人和主观意见]
假设您有一个带有不同变量的Counters
class 来检查经过的时间。 您还希望 output 每次操作的总经过时间,每 60 秒。 在此示例中, counters
是Counters
class 的一个实例,它拥有两个long
变量: fileTime
和sendTime
,它们将在特定时间间隔 ( 60s ) 内累积每个操作中的经过时间。 这只是一个假设每次迭代时间少于 1000 毫秒的示例(因此它总是显示经过时间为 60 秒):
long statsTimer = System.currentTimeMillis();
while (mustWork)
{
long elapsedStatsTimer = System.currentTimeMillis()-statsTimer; //hits 60185
if (elapsedStatsTimer > 60000)
{
//counters.showTimes()
System.out.println("Showing elapsed times for the last "+
(elapsedStatsTimer/1000)+ " secs"); //(60185/1000) - 60 secs
System.out.println("Files time: "+counters.fileTime+" ms"); //23695 ms
System.out.println("Send time : "+counters.sendTime+" ms"); //36280 ms
long workTime = counters.sendTime+counters.fileTime;
System.out.println("Work time : "+workTime+" ms"); //59975 ms
System.out.println("Others : "+(elapsedStatsTimer-workTime)+" ms"); //210 ms
//counters.reset()
counters.fileTime=0;
counters.sendTime=0;
statsTimer= System.currentTimeMillis();
}
long timer = System.currentTimeMillis();
//do something with a file
counters.fileTime+=System.currentTimeMillis-timer;
timer = System.currentTimeMillis();
//send a message
counters.sendTime+=System.currentTimeMillis()-timer;
}
Counters
class 可以实现reset()
和showTimes()
函数,以清理上面的代码。 它还可以管理elapsedStatsTimer
变量。 这只是简化其行为的示例。
对于这种需要持续测量不同操作的用例,我认为这种方式更易于使用并且似乎具有相似的性能,因为StopWatch
在内部进行完全相同的事情。 但是,嘿,这只是我的做法:)。
我将以一种光荣和徒劳的方式接受对这一观点的反对票。
我很想以一分钟的沉默来结束unsplit()
,这可能是有史以来最不相关的方法之一。
[/个人主观意见]
刚刚注意到TLDR
部分实际上比上一部分大:_)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.