gpt4 book ai didi

java - Apache Lang3 StopWatch.split()的意义是什么?

转载 作者:行者123 更新时间:2023-12-01 11:40:28 28 4
gpt4 key购买 nike

我目前正在评估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
  • 它还允许您在已停止的 watch 上检查SplitState(如果它仍处于split()状态),此时它实际上只会返回上一个splittedTime和停止时间之间的总经过时间。 (小骗子)

  • 在这种情况下,秒表同时停止并拆分,当在SPLIT之后调用start()getTime()时,它们始终显示相同的值。

    [个人和主观意见]
    假设您有一个getSplitTime()类,该类具有不同的变量来检查经过的时间。您还希望每60秒输出一次操作的总经过时间。在此示例中,stop() Counters 类的实例,该类拥有两个counters变量:Counterslong,它们将在特定时间间隔(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类可以实现sendTimeCounters函数,以清理上面的代码。它还可以管理reset()变量。这只是简化其行为的一个示例。
    对于此用例,在中,您需要持久地测量不同的操作,我认为这种方式更易于使用,并且似乎具有相似的性能,因为 showTimes() 在内部完全相同。但是,这只是我的操作方式:)。
    我将以光荣而徒劳的方式接受对此观点的否决。
    为了表达对elapsedStatsTimer的敬意,我想以一分钟的沉默结束,这可能是有史以来最不相关的方法之一。
    [/个人和主观意见]

    刚刚注意到StopWatch部分实际上大于上一部分:_)

    关于java - Apache Lang3 StopWatch.split()的意义是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62804809/

    28 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com