[英]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.