Compare commits
No commits in common. "5b2a23d06af8943b5e17a325a671fc4058b5c8df" and "a5475a460bec45e3fe368a8c31ffc6d56d3e607b" have entirely different histories.
5b2a23d06a
...
a5475a460b
79
README.md
79
README.md
@ -1,5 +1,10 @@
|
|||||||
|

|
||||||
|

|
||||||
|
|
||||||
# Fast, simple and accurate Python timing. Written in Rust.
|
# Fast, simple and accurate Python timing. Written in Rust.
|
||||||
|
|
||||||
|

|
||||||
|

|
||||||

|

|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
@ -9,76 +14,40 @@ $ python -m pip install tictoc
|
|||||||
```
|
```
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
Import.
|
Import and initialise. **The module must be initialised to be used!**
|
||||||
```python
|
```python
|
||||||
from tictoc import tic,toc
|
import tictoc
|
||||||
|
t = tictoc.init()
|
||||||
```
|
```
|
||||||
If you only want to time one section of code then use `tic() and `toc()` directly. Begin timing with `tic()`, and stop with `toc()`.
|
Begin timing with `tic()`, and stop with `toc()`.
|
||||||
```python
|
```python
|
||||||
tic()
|
t.tic()
|
||||||
# some code
|
# some code
|
||||||
toc()
|
t.toc()
|
||||||
```
|
```
|
||||||
A call to `tic()` can be followed with multiple `toc()` calls. Each will print the time elapsed since the most recent `tic()` call.
|
When `toc` is called, the results are saved. They can be accessed with the following syntax:
|
||||||
```python
|
```python
|
||||||
tic()
|
t.results.{unit}
|
||||||
time.sleep(3)
|
|
||||||
toc()
|
|
||||||
# >>> The elapsed time was 3.000132333 seconds.
|
|
||||||
time.sleep(3)
|
|
||||||
toc()
|
|
||||||
# >>> The elapsed time was 6.000383124 seconds.
|
|
||||||
```
|
|
||||||
For more complex timing operations, you can assign the output of `tic()` and pass it as an input to `toc()`.
|
|
||||||
> [!NOTE]
|
|
||||||
> This syntax cannot be used interchangeably with the default syntax above. Any call to `tic()` resets the global timer.
|
|
||||||
```python
|
|
||||||
firstTic = tic()
|
|
||||||
time.sleep(3)
|
|
||||||
secondTic = tic()
|
|
||||||
time.sleep(1)
|
|
||||||
toc(firstTic)
|
|
||||||
# >>> The elapsed time was 4.000317251 seconds.
|
|
||||||
time.sleep(3)
|
|
||||||
toc(secondTic)
|
|
||||||
# >>> The elapsed time was 4.000312568 seconds.
|
|
||||||
```
|
|
||||||
Any call to `toc()` will print the elapsed time in seconds. You can save the results with full precision by assigning the output of `toc()`.
|
|
||||||
```python
|
|
||||||
tic()
|
|
||||||
# some code
|
|
||||||
results = toc()
|
|
||||||
```
|
```
|
||||||
The available units are:
|
The available units are:
|
||||||
```python
|
```python
|
||||||
results.nanos # u128
|
t.results.nanos # u128
|
||||||
results.micros # u128
|
t.results.micros # u128
|
||||||
results.millis # u128
|
t.results.millis # u128
|
||||||
results.seconds # f64
|
t.results.seconds # f64
|
||||||
```
|
```
|
||||||
|
|
||||||
## Full example
|
## Full example
|
||||||
```python
|
```python
|
||||||
import time
|
import time
|
||||||
from tictoc import tic,toc
|
|
||||||
|
|
||||||
tic() # start timing
|
import tictoc
|
||||||
|
t = tictoc.init()
|
||||||
|
|
||||||
|
t.tic() # start timing
|
||||||
time.sleep(3) # sleep for 3 seconds
|
time.sleep(3) # sleep for 3 seconds
|
||||||
toc() # stop timing
|
t.toc() # stop timing
|
||||||
# >>> The elapsed time was 3.000132333 seconds.
|
|
||||||
|
|
||||||
firstTic = tic()
|
print(t.results.seconds)
|
||||||
time.sleep(3)
|
# >>> 3.000457715
|
||||||
secondTic = tic()
|
|
||||||
time.sleep(1)
|
|
||||||
toc(firstTic)
|
|
||||||
# >>> The elapsed time was 4.000317251 seconds.
|
|
||||||
time.sleep(3)
|
|
||||||
toc(secondTic)
|
|
||||||
# >>> The elapsed time was 4.000312568 seconds.
|
|
||||||
|
|
||||||
tic()
|
|
||||||
results = toc()
|
|
||||||
print(results.nanos)
|
|
||||||
# >>> 2825
|
|
||||||
```
|
```
|
||||||
|
25
run.py
25
run.py
@ -1,22 +1,11 @@
|
|||||||
import time
|
import time
|
||||||
from tictoc import tic,toc
|
|
||||||
|
|
||||||
tic() # start timing
|
import tictoc
|
||||||
|
|
||||||
|
t = tictoc.init()
|
||||||
|
|
||||||
|
t.tic() # start timing
|
||||||
time.sleep(3) # sleep for 3 seconds
|
time.sleep(3) # sleep for 3 seconds
|
||||||
toc() # stop timing
|
t.toc() # stop timing
|
||||||
# >>> The elapsed time was 3.000132333 seconds.
|
|
||||||
|
|
||||||
firstTic = tic()
|
print(t.results.seconds)
|
||||||
time.sleep(3)
|
|
||||||
secondTic = tic()
|
|
||||||
time.sleep(1)
|
|
||||||
toc(firstTic)
|
|
||||||
# >>> The elapsed time was 4.000317251 seconds.
|
|
||||||
time.sleep(3)
|
|
||||||
toc(secondTic)
|
|
||||||
# >>> The elapsed time was 4.000312568 seconds.
|
|
||||||
|
|
||||||
tic()
|
|
||||||
results = toc()
|
|
||||||
print(results.nanos)
|
|
||||||
# >>> 2825
|
|
||||||
|
42
src/lib.rs
42
src/lib.rs
@ -7,7 +7,7 @@ mod tictoc {
|
|||||||
use pyo3::exceptions::PyException;
|
use pyo3::exceptions::PyException;
|
||||||
|
|
||||||
#[pyclass]
|
#[pyclass]
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone)]
|
||||||
struct Results {
|
struct Results {
|
||||||
#[pyo3(get)]
|
#[pyo3(get)]
|
||||||
nanos: u128,
|
nanos: u128,
|
||||||
@ -74,7 +74,6 @@ mod tictoc {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_new() {
|
fn test_new() {
|
||||||
let init = Init::new();
|
let init = Init::new();
|
||||||
@ -85,7 +84,7 @@ mod tictoc {
|
|||||||
fn test_tic() {
|
fn test_tic() {
|
||||||
let mut init = Init::new();
|
let mut init = Init::new();
|
||||||
let time1 = init.time;
|
let time1 = init.time;
|
||||||
let _ = init.tic();
|
init.tic();
|
||||||
let time2 = init.time;
|
let time2 = init.time;
|
||||||
assert!(time2 > time1)
|
assert!(time2 > time1)
|
||||||
}
|
}
|
||||||
@ -93,40 +92,9 @@ mod tictoc {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_toc() {
|
fn test_toc() {
|
||||||
let mut init = Init::new();
|
let mut init = Init::new();
|
||||||
let _ = init.tic();
|
init.tic();
|
||||||
println!("{}","test");
|
println!("{}","test");
|
||||||
let _ = init.toc(None).unwrap();
|
let _ = init.toc();
|
||||||
assert!(init.results.nanos > 0);
|
assert!(init.results.nanos > 0)
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_passing_tic_to_toc() {
|
|
||||||
let mut init = Init::new();
|
|
||||||
let tic_obj = init.tic().unwrap();
|
|
||||||
println!("{}","test");
|
|
||||||
let results = init.toc(Some(tic_obj)).unwrap();
|
|
||||||
assert!(init.results.nanos > 0);
|
|
||||||
assert_eq!(init.results,results)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_multiple_calls() {
|
|
||||||
let mut init = Init::new();
|
|
||||||
let first_tic = init.tic().unwrap();
|
|
||||||
println!("{}","test");
|
|
||||||
let second_tic = init.tic().unwrap();
|
|
||||||
println!("{}","test");
|
|
||||||
let results2 = init.toc(Some(second_tic)).unwrap();
|
|
||||||
let results = init.toc(Some(first_tic)).unwrap();
|
|
||||||
assert!(results.nanos > results2.nanos);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_toc_before_tic() {
|
|
||||||
let mut init = Init::new();
|
|
||||||
//assert!(init.toc(None).is_err())
|
|
||||||
pyo3::prepare_freethreaded_python();
|
|
||||||
let e = init.toc(None).unwrap_err();
|
|
||||||
assert_eq!(e.to_string(),"Exception: tic() must be called before toc()")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
107
tests/test.py
107
tests/test.py
@ -1,41 +1,43 @@
|
|||||||
import pytest
|
import pytest
|
||||||
from tictoc import tic,toc
|
import tictoc
|
||||||
import time
|
import time
|
||||||
import math
|
import math
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def t():
|
||||||
|
t = tictoc.init()
|
||||||
|
return t
|
||||||
|
|
||||||
|
|
||||||
class testFunctionality:
|
class testFunctionality:
|
||||||
def testBasic(self):
|
def testBasic(self, t):
|
||||||
tic()
|
t.tic()
|
||||||
print("test")
|
print("test")
|
||||||
results = toc()
|
t.toc()
|
||||||
assert results.seconds > 0
|
assert t.results.seconds > 0
|
||||||
|
|
||||||
def testMultipleGlobalCalls(self):
|
def testOverwrite(self, t):
|
||||||
tic()
|
t.tic()
|
||||||
print("test")
|
print("test")
|
||||||
results = toc()
|
t.toc()
|
||||||
|
firstResult = t.results.seconds
|
||||||
print("test2")
|
print("test2")
|
||||||
results2 = toc()
|
t.toc()
|
||||||
|
secondResult = t.results.seconds
|
||||||
|
|
||||||
assert results.seconds < results2.seconds
|
assert firstResult < secondResult
|
||||||
|
|
||||||
def testMultipleCalls(self):
|
|
||||||
first = tic()
|
|
||||||
print("test")
|
|
||||||
second = tic()
|
|
||||||
print("test2")
|
|
||||||
secondResult = toc(second).seconds
|
|
||||||
firstResult = toc(first).seconds
|
|
||||||
|
|
||||||
assert firstResult > secondResult
|
|
||||||
|
|
||||||
|
|
||||||
class testInvalid:
|
class testInvalid:
|
||||||
def testNonTicInputForToc(self):
|
def testNoInit(self):
|
||||||
with pytest.raises(Exception):
|
with pytest.raises(Exception):
|
||||||
tic()
|
t.tic()
|
||||||
print("test")
|
|
||||||
toc(1)
|
def testTocBeforeTic(self, t):
|
||||||
|
with pytest.raises(Exception):
|
||||||
|
t.toc()
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("sleepTime", [0.05, 0.5, 1])
|
@pytest.mark.parametrize("sleepTime", [0.05, 0.5, 1])
|
||||||
class testAccuracy:
|
class testAccuracy:
|
||||||
@ -43,47 +45,42 @@ class testAccuracy:
|
|||||||
def tol(self):
|
def tol(self):
|
||||||
return 0.0006
|
return 0.0006
|
||||||
|
|
||||||
def testSingleCall(self, sleepTime, tol):
|
def testSingleCall(self, t, sleepTime, tol):
|
||||||
tic()
|
t.tic()
|
||||||
time.sleep(sleepTime)
|
time.sleep(sleepTime)
|
||||||
results = toc()
|
t.toc()
|
||||||
assert (results.seconds < sleepTime+tol)
|
assert (t.results.seconds > sleepTime) & (
|
||||||
|
t.results.seconds < (t.results.seconds + tol)
|
||||||
|
)
|
||||||
|
|
||||||
def testMultipleGlobalCalls(self, sleepTime, tol):
|
def testMultipleCalls(self, t, sleepTime, tol):
|
||||||
tic()
|
t.tic()
|
||||||
time.sleep(sleepTime)
|
time.sleep(sleepTime)
|
||||||
toc()
|
t.toc()
|
||||||
time.sleep(sleepTime)
|
time.sleep(sleepTime)
|
||||||
results = toc()
|
t.toc()
|
||||||
assert (results.seconds < (sleepTime * 2)+tol)
|
assert (t.results.seconds > sleepTime * 2) & (
|
||||||
|
t.results.seconds < (t.results.seconds + tol)
|
||||||
|
)
|
||||||
|
|
||||||
def testMultipleCalls(self, sleepTime, tol):
|
|
||||||
first = tic()
|
|
||||||
time.sleep(sleepTime)
|
|
||||||
second = tic()
|
|
||||||
time.sleep(sleepTime)
|
|
||||||
results2 = toc(second)
|
|
||||||
results = toc(first)
|
|
||||||
assert (results.seconds < (sleepTime * 2)+tol)
|
|
||||||
assert (results2.seconds < sleepTime+tol)
|
|
||||||
|
|
||||||
class testConsistency:
|
class testConsistency:
|
||||||
def testMicros(self):
|
def testMicros(self, t):
|
||||||
tic()
|
t.tic()
|
||||||
print("test")
|
print("test")
|
||||||
results = toc()
|
t.toc()
|
||||||
assert results.micros == (math.floor(results.nanos * pow(10, -3)))
|
assert t.results.micros == (math.floor(t.results.nanos * pow(10, -3)))
|
||||||
|
|
||||||
def testMillis(self):
|
def testMillis(self, t):
|
||||||
tic()
|
t.tic()
|
||||||
print("test")
|
print("test")
|
||||||
results = toc()
|
t.toc()
|
||||||
assert results.millis == (math.floor(results.nanos * pow(10, -6)))
|
assert t.results.millis == (math.floor(t.results.nanos * pow(10, -6)))
|
||||||
|
|
||||||
def testSeconds(self):
|
def testSeconds(self, t):
|
||||||
tic()
|
t.tic()
|
||||||
print("test")
|
print("test")
|
||||||
results = toc()
|
t.toc()
|
||||||
assert results.seconds == round(
|
assert t.results.seconds == round(
|
||||||
(results.nanos * pow(10, -9)), 9
|
(t.results.nanos * pow(10, -9)), 9
|
||||||
) # f64 vs u128, hence the round
|
) # f64 vs u128, hence the round
|
||||||
|
@ -1,82 +0,0 @@
|
|||||||
import pytest
|
|
||||||
import tictoc
|
|
||||||
import time
|
|
||||||
import math
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
|
||||||
def t():
|
|
||||||
t = tictoc.init()
|
|
||||||
return t
|
|
||||||
|
|
||||||
|
|
||||||
class testFunctionality:
|
|
||||||
def testBasic(self, t):
|
|
||||||
t.tic()
|
|
||||||
print("test")
|
|
||||||
t.toc()
|
|
||||||
assert t.results.seconds > 0
|
|
||||||
|
|
||||||
def testOverwrite(self, t):
|
|
||||||
t.tic()
|
|
||||||
print("test")
|
|
||||||
t.toc()
|
|
||||||
firstResult = t.results.seconds
|
|
||||||
print("test2")
|
|
||||||
t.toc()
|
|
||||||
secondResult = t.results.seconds
|
|
||||||
|
|
||||||
assert firstResult < secondResult
|
|
||||||
|
|
||||||
|
|
||||||
class testInvalid:
|
|
||||||
def testNoInit(self):
|
|
||||||
with pytest.raises(Exception):
|
|
||||||
t.tic()
|
|
||||||
|
|
||||||
def testTocBeforeTic(self, t):
|
|
||||||
with pytest.raises(Exception):
|
|
||||||
t.toc()
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("sleepTime", [0.05, 0.5, 1])
|
|
||||||
class testAccuracy:
|
|
||||||
@pytest.fixture(scope="class")
|
|
||||||
def tol(self):
|
|
||||||
return 0.0006
|
|
||||||
|
|
||||||
def testSingleCall(self, t, sleepTime, tol):
|
|
||||||
t.tic()
|
|
||||||
time.sleep(sleepTime)
|
|
||||||
t.toc()
|
|
||||||
assert (t.results.seconds < sleepTime+tol)
|
|
||||||
|
|
||||||
def testMultipleCalls(self, t, sleepTime, tol):
|
|
||||||
t.tic()
|
|
||||||
time.sleep(sleepTime)
|
|
||||||
t.toc()
|
|
||||||
time.sleep(sleepTime)
|
|
||||||
t.toc()
|
|
||||||
assert (t.results.seconds < (sleepTime * 2)+tol)
|
|
||||||
|
|
||||||
|
|
||||||
class testConsistency:
|
|
||||||
def testMicros(self, t):
|
|
||||||
t.tic()
|
|
||||||
print("test")
|
|
||||||
t.toc()
|
|
||||||
assert t.results.micros == (math.floor(t.results.nanos * pow(10, -3)))
|
|
||||||
|
|
||||||
def testMillis(self, t):
|
|
||||||
t.tic()
|
|
||||||
print("test")
|
|
||||||
t.toc()
|
|
||||||
assert t.results.millis == (math.floor(t.results.nanos * pow(10, -6)))
|
|
||||||
|
|
||||||
def testSeconds(self, t):
|
|
||||||
t.tic()
|
|
||||||
print("test")
|
|
||||||
t.toc()
|
|
||||||
assert t.results.seconds == round(
|
|
||||||
(t.results.nanos * pow(10, -9)), 9
|
|
||||||
) # f64 vs u128, hence the round
|
|
Loading…
x
Reference in New Issue
Block a user