On Fri, Mar 26, 2010 at 09:01:35AM +0100, Florent hivert wrote:
> >> MORAL: If you care about speed, don't use the cached_method decorator
> >> yet.   It entails massive overheard.
>
> I'm very sorry to says that Nicolas and I are well aware of this problem since
> a long time. We have been cursing this a lot more than once. We have been lazy
> not at least putting a ticket on track... Many apologies for this.

Yup.

> -1 for not using cached method:
>
> Througout sage library there are a dozen of different looking implementations
> for caching some computation. That's a lot of unnecessary code which is very
> likely to cause problems upon pickling unpickling (should we pickle or drop
> the cache), and even more renders nearly impossible to consistently clear the
> cache. I'm strongly in favor of standardization.

In code that goes into Sage. Of course in your own code, that can be a
reasonable temporary workaround.

> +10 for optimizing it.

Pleaaaase!

Besides speed, making the critical path shorter will also make it far
more comfortable when running the debugger. Right now, any call to a
cached method requires a lot of stepping through.

By the way, when doing:

    sage: C = Rings()
    sage: C.super_categories?

(my favorite cached function), one still gets beside the doc of
super_categories, a lot of irrelevant documentation about
cached_functions, which is confusing. Ideally,
functools.update_wrapper would handle this; there was a discussion on
trac about this, but I don't remember the outcome.

Last thing: one feature that could be nice would be to have any
SageObject x have a "_cache" attribute, which would be a dictionary
which would contain the cache of all the (cached_) methods of x. For
example:

   x._cache["blah0"]                  # The value  of x.blah0()
   x._cache["blah1"][3]               # The result of x.blah1(3)
   x._cache["blah2"][(1,3)]           # The result of x.blah2(1,3)
   x._cache["blah3"][((1,3), {"a":1})]# The result of x.blah3(1,3)
   x._cache["blah3"][((1,3), {"a":3})]# The result of x.blah3(1,3, a=3)

where I am assuming the following defs:

   def blah0(self): ...
   def blah1(self, x): ...
   def blah2(self, x, y): ...
   def blah3(self, x, y, a=1): ...

(I use the occasion to suggest using different keys depending on the
number of arguments / keyword arguments the method takes).

The advantage would be that clearing the cache (for example upon a
copy, ...) would be trivial. Also, this would reduce the amount of
stuff in x._<tab>. The downside would be another attribute/dict lookup
in the critical path; if _cache is a Cython attribute, that should be
negligible, but one might not want to throw in yet another Cython
attribute in all SageObjects.

In any cases, and as William would put it: whoever handles any of the
above will be a hero!

Cheers,
                                Nicolas
--
Nicolas M. ThiƩry "Isil" <nthi...@users.sf.net>
http://Nicolas.Thiery.name/

-- 
To post to this group, send an email to sage-devel@googlegroups.com
To unsubscribe from this group, send an email to 
sage-devel+unsubscr...@googlegroups.com
For more options, visit this group at http://groups.google.com/group/sage-devel
URL: http://www.sagemath.org

To unsubscribe from this group, send email to 
sage-devel+unsubscribegooglegroups.com or reply to this email with the words 
"REMOVE ME" as the subject.

Reply via email to