Opened 6 years ago
Last modified 6 years ago
#16792 new defect
cached_function.clear_cache is inefficent
Reported by: | dkrenn | Owned by: | |
---|---|---|---|
Priority: | major | Milestone: | sage-6.4 |
Component: | misc | Keywords: | |
Cc: | Merged in: | ||
Authors: | Reviewers: | ||
Report Upstream: | N/A | Work issues: | |
Branch: | Commit: | ||
Dependencies: | Stopgaps: |
Description
@cached_function def noop(): return None R = Zmod(42) D = dict((x^k, R(k)^k) for k in srange(1000000)) E = copy(D) timeit("E.clear()", number=1) noop.cache = copy(D) timeit("noop.clear_cache()", number=1)
gives
1 loops, best of 3: 954 ns per loop 1 loops, best of 3: 9.56 ms per loop
This is because .clear_cache
does
cdef object cache = self.cache for key in cache.keys(): del cache[key]
which is very inefficient for large caches.
Change History (3)
comment:1 Changed 6 years ago by
comment:2 Changed 6 years ago by
Your point is probably correct, but your code timing doesn't really corroborate it. Timeit, as used, it still repeating the command thrice. It's a mutating command, so the second time around, the original length of the dict doesn't come into play at all.
sage: %time E.clear() CPU times: user 11 ms, sys: 6 ms, total: 17 ms sage: %time noop.clear_cache() CPU times: user 59 ms, sys: 5 ms, total: 64 ms Wall time: 64 ms
probably gives a fairer picture. Your original numbers would have meant that E.clear()
would have visited al 1000000 entries (they all have to be decreffed!) in less than 1 microsecond, meaning your computer would be performing more than 1012 operations per second. Terahertz performance is usually not so easily attained.
comment:3 Changed 6 years ago by
- Milestone changed from sage-6.3 to sage-6.4
Is there a reason why not using
self.cache.clear()
?