Opened 7 years ago

Last modified 7 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:

Status badges

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 7 years ago by dkrenn

Is there a reason why not using self.cache.clear()?

comment:2 Changed 7 years ago by nbruin

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.

Last edited 7 years ago by nbruin (previous) (diff)

comment:3 Changed 7 years ago by vbraun_spam

  • Milestone changed from sage-6.3 to sage-6.4
Note: See TracTickets for help on using tickets.