Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

make use of time.clock_gettime_ns() #14

Open
socketpair opened this issue Oct 27, 2023 · 5 comments
Open

make use of time.clock_gettime_ns() #14

socketpair opened this issue Oct 27, 2023 · 5 comments

Comments

@socketpair
Copy link

It is faster and without floating point. Just time.clock_gettime_ns() // 1000000 to get milliseconds.

@akx
Copy link
Member

akx commented Oct 30, 2023

On my machine, int(time.time() * 1000.0) seems to be slightly faster than time.clock_gettime_ns(time.CLOCK_REALTIME) // 1000000:

~ $ python3 -m timeit -s 'import time' 'time.clock_gettime_ns(time.CLOCK_REALTIME) // 1000000'
5000000 loops, best of 5: 71.7 nsec per loop
~ $ python3 -m timeit -s 'import time' 'int(time.time() * 1000.0)'
5000000 loops, best of 5: 63.3 nsec per loop

or more broadly

$ hyperfine "python3 -m timeit -s 'import time' 'int(time.time() * 1000.0)'" "python3 -m timeit -s 'import time' 'time.clock_gettime_ns(time.CLOCK_REALTIME) // 1000000'"
Benchmark 1: python3 -m timeit -s 'import time' 'int(time.time() * 1000.0)'
  Time (mean ± σ):      2.182 s ±  0.010 s    [User: 2.123 s, System: 0.057 s]
  Range (min … max):    2.167 s …  2.198 s    10 runs

Benchmark 2: python3 -m timeit -s 'import time' 'time.clock_gettime_ns(time.CLOCK_REALTIME) // 1000000'
  Time (mean ± σ):      2.513 s ±  0.025 s    [User: 2.448 s, System: 0.063 s]
  Range (min … max):    2.468 s …  2.536 s    10 runs

Summary
  python3 -m timeit -s 'import time' 'int(time.time() * 1000.0)' ran
    1.15 ± 0.01 times faster than python3 -m timeit -s 'import time' 'time.clock_gettime_ns(time.CLOCK_REALTIME) // 1000000'
~ $

@socketpair
Copy link
Author

Hm, you are right. My measurements:

In [3]: timeit int(time.time() * 1000.0)
74.1 ns ± 0.951 ns per loop (mean ± std. dev. of 7 runs, 10,000,000 loops each)

In [4]: timeit time.clock_gettime_ns(time.CLOCK_REALTIME) // 1000000
93.9 ns ± 1.09 ns per loop (mean ± std. dev. of 7 runs, 10,000,000 loops each)

In [5]: qwe=time.CLOCK_REALTIME

In [6]: timeit time.clock_gettime_ns(qwe) // 1000000
87.1 ns ± 0.426 ns per loop (mean ± std. dev. of 7 runs, 10,000,000 loops each)

@socketpair
Copy link
Author

socketpair commented Oct 30, 2023

It seems the only cause of slowness is the passing argument for the function. But anyway: reported here: python/cpython#111482

@akx
Copy link
Member

akx commented Oct 30, 2023

Sure - should we use the old micro-optimization tricks of localizing global name lookups we'd probably be a bit faster, but at the expense of not being able to e. g. easily use freezegun or other time-mocking libraries.

If you need to generate gazillions of ULIDs as fast as possible, you'd probably want to use a native-code extension instead, eg https://github.com/bdraco/ulid-transform

@akx
Copy link
Member

akx commented Jul 24, 2024

Looks like we could use clock.gettime_ns() in 3.13 as python/cpython@4fe22c7 was merged.

Thanks for the upstream bug report!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants