Skip to content

Commit 532aa1b

Browse files
committed
refactor for multiple timers
1 parent aa640d9 commit 532aa1b

File tree

3 files changed

+136
-65
lines changed

3 files changed

+136
-65
lines changed

README.md

Lines changed: 36 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -3,68 +3,78 @@
33
![tick tock](images/ticktock.gif)
44

55

6-
| **PackageEvaluator** | **Build Status** |
7-
|:-------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------:|
6+
| **PackageEvaluator** | **Build Status** |
7+
|:---:|:---:|
88
|[![][pkg-0.6-img]][pkg-0.6-url] [![][pkg-0.7-img]][pkg-0.7-url] | [![][travis-img]][travis-url] [![][appveyor-img]][appveyor-url] [![][codecov-img]][codecov-url] |
99

10-
11-
12-
This module provides `tick()`, `tock()`, and `tok()` functions. They're similar to the `tic()`, `toc()`, and `toq()` functions that you might find in MATLAB and similar software. There are also `lap()` and `peek()` functions that reveal the state of the current timer without stopping it.
10+
This module provides `tick()`, `tock()`, and `tok()` functions. They're similar to the `tic()`, `toc()`, and `toq()` functions that you might find in MATLAB and similar software. There are also `laptime()` and `peektime()` functions that reveal the state of the current timers without stopping them.
1311

1412
**Don't use these for timing code execution!** Julia provides much better facilities for measuring performance, ranging from the `@time` and `@elapsed` macros to packages such as [BenchmarkTools.jl](https://github.com/JuliaCI/BenchmarkTools.jl). (And remember, don't time Julia code running in global scope!) The [TimerOutputs.jl](https://github.com/KristofferC/TimerOutputs.jl) package provides tools for timing different sections of a program.
1513

1614
## Functions
1715

18-
- `tick()` start counting
19-
- `tock()` stop counting, show total elapsed time
20-
- `tok()` stop counting, return seconds
21-
- `peek()` continue counting, return elapsed seconds
22-
- `lap()` continue counting, show total elapsed time
16+
- `tick() ` start timing
17+
- `tock() ` stop timing, show total elapsed time
18+
- `tok() ` stop timing, return elapsed seconds
19+
- `peektime() ` continue timing, return elapsed seconds
20+
- `laptimer() ` continue timing, show total elapsed time
2321

2422
## Suggestions for use
2523

2624
You can:
2725

2826
- time how long a phone call takes without leaving the Julia REPL
2927

30-
```
28+
```julia
3129
julia-0.6> using TickTock
3230
julia-0.6> tick()
33-
Started timer: 2017-12-13T22:30:59.632.
31+
Started timer at 2017-12-13T22:30:59.632
3432
julia-0.6> tock()
3533
55.052638936 ms: 55 seconds, 52 milliseconds
3634
```
3735

3836
- see how long your cup of tea's been brewing:
3937

40-
```
38+
```julia
4139
julia-0.6> tick()
42-
Started timer: 2017-12-13T22:34:03.78.
43-
julia-0.6> lap()
44-
72.625839832 ms: 1 minute, 12 seconds, 625 milliseconds
45-
julia-0.6> lap()
46-
266.053953749 ms: 4 minutes, 26 seconds, 53 milliseconds
47-
julia-0.6> lap()
48-
285.314459174 ms: 4 minutes, 45 seconds, 314 milliseconds
40+
Started timer at 2017-12-13T22:34:03.78
41+
julia-0.6> laptimer()
42+
72.625839832 ms: 1 minute, 12 seconds, 625 milliseconds
43+
julia-0.6> laptimer()
44+
266.053953749 ms: 4 minutes, 26 seconds, 53 milliseconds
45+
julia-0.6> laptimer()
46+
285.314459174 ms: 4 minutes, 45 seconds, 314 milliseconds
4947
```
5048

5149
- see how many seconds you held your breath for:
5250

53-
```
51+
```julia
5452
julia-0.6> tick()
55-
Started timer at 2017-12-12T09:17:45.504.
53+
Started timer at 2017-12-12T09:17:45.504
5654

5755
julia-0.6> tok()
5856
287.841546621
5957
```
6058

6159
- see how long your computer (and Julia session) has been running for:
6260

63-
```
61+
```julia
6462
julia-0.6> tick()
65-
...
66-
julia-0.6> lap()
67-
1.302200135485876e6s: (2 weeks, 1 day, 1 hour, 43 minutes, 20 seconds, 135 milliseconds)
63+
...go on holiday, then come back
64+
julia-0.6> laptimer()
65+
1.302200135485876e6s: 2 weeks, 1 day, 1 hour, 43 minutes, 20 seconds, 135 milliseconds
66+
```
67+
68+
- time a number of things:
69+
70+
```julia
71+
julia-0.7> tick()
72+
started timer at: 2018-03-17T12:08:43.326
73+
julia-0.7> tick()
74+
started timer at: 2018-03-17T12:14:03.077
75+
julia-0.7> laptimer()
76+
2 7.315769543s: 7 seconds, 315 milliseconds
77+
1 327.074715234s: 5 minutes, 27 seconds, 74 milliseconds
6878
```
6979

7080
You should *not* use this package to:
@@ -78,7 +88,6 @@ You should *not* use this package to:
7888
Some of this code used to live in Julia Base in the `tic()`, `toc()`, and `toq()` functions
7989
(in base/util.jl). They were deprecated in GitHub issue [17046](https://github.com/JuliaLang/julia/issues/17046).
8090

81-
8291
[travis-img]: https://travis-ci.org/cormullion/TickTock.jl.svg?branch=master
8392
[travis-url]: https://travis-ci.org/cormullion/TickTock.jl
8493

src/TickTock.jl

Lines changed: 53 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,9 @@ time Julia code running in global scope!)
1212
This code used to live in Julia Base as the `tic()`, `toc()`, and `toq()` functions
1313
(in base/util.jl). They were deprecated in GitHub issue [17046](https://github.com/JuliaLang/julia/issues/17046).
1414
"""
15-
1615
module TickTock
1716

18-
export tick, tock, tok, peek, lap
17+
export tick, tock, tok, peektimer, laptimer
1918

2019
if VERSION > v"0.7.0-"
2120
using Dates # for now() :(
@@ -26,27 +25,48 @@ end
2625
2726
Start counting. The other functions are:
2827
29-
- `tock()` stop counting, show total elapsed time in canonical form
30-
- `tok()` stop counting, return seconds
31-
- `peek()` continue counting, return elapsed seconds
32-
- `lap()` continue counting, show total elapsed time in canonical form
28+
- `tock()` ` stop counting, show total elapsed time in canonical form
29+
- `tok()` ` stop counting, return seconds
30+
- `peektimer() ` continue counting, return elapsed seconds
31+
- `laptimer() ` continue counting, show total elapsed time in canonical form
3332
"""
3433
function tick()
3534
t0 = time_ns()
3635
task_local_storage(:TIMERS, (t0, get(task_local_storage(), :TIMERS, ())))
37-
println("Started timer: $(now()).")
36+
println(" started timer at: $(now())")
37+
end
38+
39+
function printcanonical(tnow)
40+
canondc = Dates.canonicalize(
41+
Dates.CompoundPeriod(Dates.Second(floor(tnow)),
42+
Dates.Millisecond(floor( (tnow - floor(tnow)) * 1000))))
43+
println("$(lpad(tnow, 20))s: $canondc")
44+
end
45+
46+
function gettimers()
47+
result = UInt64[]
48+
timers = get(task_local_storage(), :TIMERS, ())
49+
if timers === ()
50+
error("Use `tick()` to start a timer.")
51+
end
52+
while timers[2] != ()
53+
push!(result, timers[1]::UInt64)
54+
timers = timers[2]
55+
end
56+
push!(result, timers[1]::UInt64)
57+
return result
3858
end
3959

4060
"""
41-
peek()
61+
peektimer()
4262
43-
Return the current elapsed seconds counted by the current timer, without stopping it.
63+
Return the current elapsed seconds counted by the most recent timer, without stopping it.
4464
"""
45-
function peek()
65+
function peektimer()
4666
t1 = time_ns()
4767
timers = get(task_local_storage(), :TIMERS, ())
4868
if timers === ()
49-
error("You must first use `tick()`.")
69+
error("Use `tick()` to start a timer.")
5070
end
5171
t0 = timers[1]::UInt64
5272
return (t1 - t0)/1e9
@@ -55,44 +75,49 @@ end
5575
"""
5676
tok()
5777
58-
Return the seconds since the previous `tick()` then stop counting.
78+
Return the current elapsed seconds counted by the most recent timer, then stop counting.
5979
"""
6080
function tok()
6181
timers = get(task_local_storage(), :TIMERS, ())
6282
if timers === ()
63-
error("You must first use `tick()`.")
83+
error("Use `tick()` to start a timer.")
6484
end
65-
t = peek()
85+
t = peektimer()
6686
task_local_storage(:TIMERS, timers[2])
6787
return t
6888
end
6989

7090
"""
7191
tock()
7292
73-
Print the elapsed time, in canonical form, since the previous `tick()`,
74-
then stop counting.
93+
Print the elapsed time, in canonical form, of the most recent timer, then stop counting.
7594
"""
7695
function tock()
7796
t = tok()
78-
canondc = Dates.canonicalize(
79-
Dates.CompoundPeriod(Dates.Second(floor(t)),
80-
Dates.Millisecond(floor( (t - floor(t)) * 1000))))
81-
println("$(t)s: ($canondc)")
97+
printcanonical(t)
98+
end
99+
100+
function showtimes(;canonical=true)
101+
t1 = time_ns()
102+
timers = gettimers()
103+
if timers === ()
104+
error("Use `tick()` to start a timer.")
105+
end
106+
timernumber = length(timers)
107+
for t0 in timers
108+
tnow = (t1 - t0)/1e9
109+
print(rpad(timernumber, 10))
110+
canonical ? printcanonical(tnow) : println(tnow)
111+
timernumber -= 1
112+
end
82113
end
83114

84115
"""
85-
lap()
116+
laptimer()
86117
87118
Print the current elapsed time, in canonical form, since the previous `tick()`,
88119
and continue counting.
89120
"""
90-
function lap()
91-
t = peek()
92-
canondc = Dates.canonicalize(
93-
Dates.CompoundPeriod(Dates.Second(floor(t)),
94-
Dates.Millisecond(floor( (t - floor(t)) * 1000))))
95-
println("$(t)s: ($canondc)")
96-
end
121+
laptimer() = showtimes(canonical=true)
97122

98123
end # module

test/runtests.jl

Lines changed: 47 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,73 @@
1-
using TickTock
2-
31
if VERSION > v"0.7.0-"
2+
using Pkg
43
using Test
54
else
65
using Base.Test
76
end
87

8+
using TickTock
9+
910
tick()
1011

1112
sleep(1)
1213

13-
@test typeof(peek()) == Float64
14+
@test typeof(peektimer()) == Float64
1415

1516
if VERSION > v"0.7.0-"
16-
@test sprint(showcompact, lap()) == "nothing"
17+
@test sprint(show, laptimer(), context=:compact => true) == "nothing"
1718
else
18-
@test typeof(lap()) == Void
19+
@test typeof(laptimer()) == Void
1920
end
2021

21-
2222
@test tok() > 1.0
2323

2424
tick()
2525

2626
if VERSION > v"0.7.0-"
27-
@test sprint(showcompact, tock()) == "nothing"
27+
@test sprint(show, tock(), context=:compact => true) == "nothing"
2828
else
2929
@test typeof(tock()) == Void
3030
end
3131

32-
# with no current timer, these should error
32+
println("Make 10 timers")
33+
34+
for i in 1:10
35+
tick()
36+
sleep(1)
37+
end
38+
39+
@test length(TickTock.gettimers()) == 10
40+
41+
println("Check that there are 10 timers")
42+
43+
println("wait a second")
44+
45+
sleep(1)
46+
47+
println("Print all the timers")
48+
49+
laptimer()
50+
51+
52+
for i in 1:10
53+
peektimer()
54+
end
55+
56+
println("Check that the most recent timer is more than 1 second")
57+
58+
println(peektimer())
59+
60+
@test peektimer() > 1.0
61+
62+
println("Finish 10 timers and show canonical")
63+
64+
for i in 1:10
65+
tock()
66+
end
67+
68+
# now, with no current timers, these should all error
3369

34-
@test_throws ErrorException peek()
35-
@test_throws ErrorException lap()
70+
@test_throws ErrorException TickTock.gettimers()
71+
@test_throws ErrorException peektimer()
72+
@test_throws ErrorException laptimer()
3673
@test_throws ErrorException tok()

0 commit comments

Comments
 (0)