我目前正在评估Apache StopWatch和Guava的Stopwatch之间的实现,前者中的拆分功能引起了我的兴趣,但我一直在努力了解它的确切功能和值(value)。
根据StopWatch的文档:https://commons.apache.org/proper/commons-lang/javadocs/api-3.9/org/apache/commons/lang3/time/StopWatch.html
split() the watch to get the time whilst the watch continues in the background. unsplit() will remove the effect of the split. At this point, these three options are available again.
而且我发现了一些示例,例如this,由于拆分似乎只是累积性的,所以提供的很少。页面上说该方法用于“拆分时间”,我根据该方法认为这是最多的,但是页面未提及这实际上意味着什么。甚至看起来这个例子是完全错误的,因为文档建议您应该在再次使用
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秒,但似乎这两种方法都输出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()
调用没有区别...我也尝试过此操作,并且对我来说,时间仍然是一样的。我在这里错过了什么吗?还是我对这应该做的一切的解释都是错的?
最佳答案
这是的source code getSplitTime()
(内部调用此其他函数):
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()
时,该变量将被覆盖。尽管共享相同的变量可能看起来有些奇怪,但这确实是有道理的,因为的
splittedTime
StopWatch
不应大于总经过时间。因此,这是一个有关 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()
函数的简单性(这也几乎不能回答OP的问题)。它负责:StopWatch
是否正在运行。 stopTime
。 splitState
设置为 SPLIT
。 TLDR lol
在停止getSplitTime()
之前调用StopWatch
应该会向您显示所需的值:stopTime
和 stop()
之间经过的时间匹配。 一些示例:(是的,在星期六晚上进行编辑,因为我需要社交生活)
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
还有最后一个。您知道,这是用split()
模拟时间的,只是为了好玩。我很无聊,我真的进口了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
请注意,在停止的上
startTime
上调用sleeps
不会引发任何异常,因为该方法仅在getSplitTime()
为时才会检查Watch
。混淆可能是由以下两个事实引起的:
splitState
而不考虑SPLIT
,从而使最后一个stop()
毫无用处。徒劳的,我喜欢这个词。必须以某种方式将其包括在我的答案中。 Futileeee SplitState
(如果它仍处于split()
状态),此时它实际上只会返回上一个splittedTime
和停止时间之间的总经过时间。 (小骗子)在这种情况下,秒表同时停止并拆分,当在
SPLIT
之后调用start()
和getTime()
时,它们始终显示相同的值。[个人和主观意见]
假设您有一个
getSplitTime()
类,该类具有不同的变量来检查经过的时间。您还希望每60秒输出一次操作的总经过时间。在此示例中,stop()
是 Counters
类的实例,该类拥有两个counters
变量:Counters
和long
,它们将在特定时间间隔(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;
}
该fileTime
类可以实现sendTime
和Counters
函数,以清理上面的代码。它还可以管理reset()
变量。这只是简化其行为的一个示例。对于此用例,在中,您需要持久地测量不同的操作,我认为这种方式更易于使用,并且似乎具有相似的性能,因为
showTimes()
在内部完全相同。但是,这只是我的操作方式:)。我将以光荣而徒劳的方式接受对此观点的否决。
为了表达对
elapsedStatsTimer
的敬意,我想以一分钟的沉默结束,这可能是有史以来最不相关的方法之一。[/个人和主观意见]
刚刚注意到
StopWatch
部分实际上大于上一部分:_)
关于java - Apache Lang3 StopWatch.split()的意义是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62804809/