3

Context: I'm implementing a memory cache with TTLs in my Python project, and it has to withstand considerable throughput. To determine when a cache record goes stale, I save it with a timestamp, and when I retrieve it later I check this timestamp against the current time. If the difference is above the threshold, the record is stale and should be discarded.

Question: time.time() or time.perf_counter() — which function returns its value faster? Is the difference considerable or negligible?

2 Answers2

16

The choice between time.time() and time.perf_counter() depends on the context in which you will use the function. That's because each function deals with a different "type of time".

time.time() deals with absolute time, i.e., "real-world time" (the type of time we're used to). It's measured from a fixed point in the past. According to the docs, time.time() returns:

(...) the time in seconds since the epoch as a floating point number.

time.perf_counter(), on the other hand, deals with relative time, which has no defined relationship to real-world time (i.e., the relationship is unknown to us and depends on several factors). It's measured using a CPU counter and, as specified in the docs, should only be used to measure time intervals:

The reference point of the returned value is undefined, so that only the difference between the results of consecutive calls is valid.

Because of that, time.perf_counter() is mostly used to compare performance.


That said, I don't think there is any point in comparing the speed of those two functions. They were designed to be used for different things - you should pick the one that best suits your use case. Quoting a comment by @Martijn Pieters:

Sometimes you need a hammer, sometimes you need a screwdriver. You don't ask if one or the other is faster; you either have a nail or a screw. Trying to use a screwdriver on a nail may work, but is not the best choice.

From what I've gathered from your comment, you're probably better off using time.perf_counter(), since your focus is in relative time and not in "real-world time". In such a context, time.perf_counter() is probably going to be more precise, because it uses:

(...) a clock with the highest available resolution to measure a short duration.

Talendar
  • 1,841
  • 14
  • 23
  • 1
    @Talendar: No, you didn't understand my use-case right. I am dealing with "timestamps" only in a sense that they are points in time used to calculate the length of timespan between them, but there is no reason to limit them to points of real-world time. Relative system-specific time is fine too, as long as its second is as long as a real-world second. (Yes, I wil not trade these "timestamps" between different systems, so system-specific is fine.) Your whole lenghty answer will be much appreciated by those in search of such information, but it is completely irrelevant in my case. – Владислав Савенков Feb 04 '21 at 09:51
  • @Владислав Савенков: I've updated my answer, I hope it will be more useful to you now. I'm sorry I can't help more. Cheers! – Talendar Feb 04 '21 at 12:57
6

I did a benchmark to find out


> py -m timeit -s "from time import perf_counter as time" -n 10000000 "time()"
10000000 loops, best of 5: 132 nsec per loop
> py -m timeit -s "from time import time" -n 10000000 "time()"
10000000 loops, best of 5: 69.6 nsec per loop
> py -m timeit -s "from time import perf_counter as time" -n 10000000 "time()"
10000000 loops, best of 5: 126 nsec per loop
> py -m timeit -s "from time import time" -n 10000000 "time()"
10000000 loops, best of 5: 75.9 nsec per loop
> py -V
Python 3.10.1

We can conclude that time.time() is nearly twice as fast than time.perf_counter()

However the magnitude of the difference is very low, ~56 nanosec

To put that into perspective it is only ~168 clock cycles slower on a 3ghz cpu

WizzyGeek
  • 101
  • 2
  • 10