Skip to content

Commit 1be1f9d

Browse files
author
michaldo
committed
SimpleStopWatch is alternative for overcomplicated and buggy StopWatch
1 parent a149529 commit 1be1f9d

File tree

2 files changed

+164
-0
lines changed

2 files changed

+164
-0
lines changed
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package org.apache.commons.lang3.time;
19+
20+
/**
21+
* <p>
22+
* {@link SimpleStopWatch} provides a convenient API for timings.
23+
* </p>
24+
* <p>
25+
* {@link SimpleStopWatch} is simple alternative for {@link StopWatch}. It does not have state flow
26+
* and API is no-brainer.
27+
* </p>
28+
* <p>
29+
* {@link SimpleStopWatch} use {@link System#nanoTime()} for time measure.
30+
* </p>
31+
32+
*
33+
* <p>
34+
* To start the watch, call {@link SimpleStopWatch#started()}.
35+
* </p>
36+
* <p>
37+
* To get time in millis since start, call {@link #time()}.
38+
* </p>
39+
* <p>
40+
* {@link #lap()} returns time in millis since last {@link #lap()} call or since start
41+
* when {@link #lap()} not called yet. For example:<br>
42+
* 1. var stopWatch = SimpleStopWatch.started()<br>
43+
* 2. sleep (200 ms)<br>
44+
* 3. stopWatch.getTime() == 200, stopWatch.lap() == 200<br>
45+
* 4. sleep (100 ms)<br>
46+
* 5. stopWatch.getTime() == 300, stopWatch.lap() == 100<br>
47+
48+
* <p>This class is not thread-safe.</p>
49+
*
50+
* @since 3.12
51+
*/
52+
public class SimpleStopWatch {
53+
54+
55+
private static final long NANO_2_MILLIS = 1000000L;
56+
57+
/**
58+
* Creates a simple stop watch.<br>
59+
* To avoid doubts for people used to {@link StopWatch} method name explains
60+
* that SimpleStopWatch is started when created.
61+
*
62+
* @return SimpleStopWatch a stopwatch.
63+
*/
64+
public static SimpleStopWatch started() {
65+
return new SimpleStopWatch();
66+
}
67+
68+
69+
/**
70+
* The start time in nanoseconds.
71+
*/
72+
private long startTimeNanos;
73+
74+
75+
/**
76+
* The lap start time in nanoseconds.
77+
*/
78+
private long lapStartTimeNanos;
79+
80+
81+
private SimpleStopWatch() {
82+
this.startTimeNanos = System.nanoTime();
83+
this.lapStartTimeNanos = startTimeNanos;
84+
}
85+
86+
/**
87+
* <p>
88+
* Gets the time on the stopwatch.
89+
* </p>
90+
*
91+
* @return the time in milliseconds
92+
*/
93+
public long time() {
94+
return (System.nanoTime() - this.startTimeNanos) / NANO_2_MILLIS;
95+
}
96+
97+
/**
98+
* <p>
99+
* Gets the time on the stopwatch since last ${lap} call or since start when ${lap} not called yet
100+
* </p>
101+
*
102+
* @return the time in milliseconds
103+
*/
104+
public long lap() {
105+
long lapTime = (System.nanoTime() - lapStartTimeNanos) / NANO_2_MILLIS;
106+
lapStartTimeNanos = System.nanoTime();
107+
return lapTime;
108+
}
109+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package org.apache.commons.lang3.time;
18+
19+
import org.junit.jupiter.api.Test;
20+
21+
import static org.junit.jupiter.api.Assertions.assertAll;
22+
import static org.junit.jupiter.api.Assertions.assertTrue;
23+
24+
/**
25+
* TestCase for SimpleStopWatch.
26+
*/
27+
class SimpleStopWatchTest {
28+
29+
@Test
30+
void testSimpleStopWatch() throws InterruptedException {
31+
SimpleStopWatch simpleStopWatch = SimpleStopWatch.started();
32+
33+
{
34+
Thread.sleep(500);
35+
long time500 = simpleStopWatch.time();
36+
long lap500 = simpleStopWatch.lap();
37+
assertAll(
38+
() -> assertTrue(time500 > 450, String.valueOf(time500)),
39+
() -> assertTrue(time500 < 550, String.valueOf(time500)),
40+
() -> assertTrue(lap500 > 450, String.valueOf(lap500)),
41+
() -> assertTrue(lap500 < 550, String.valueOf(lap500)));
42+
}
43+
{
44+
Thread.sleep(300);
45+
long time800 = simpleStopWatch.time();
46+
long lap300 = simpleStopWatch.lap();
47+
48+
assertAll(
49+
() -> assertTrue(time800 > 750, String.valueOf(time800)),
50+
() -> assertTrue(time800 < 900, String.valueOf(time800)),
51+
() -> assertTrue(lap300 > 250, String.valueOf(lap300)),
52+
() -> assertTrue(lap300 < 350, String.valueOf(lap300)));
53+
}
54+
}
55+
}

0 commit comments

Comments
 (0)