On Jun 14, 2010, at 4:19 PM, Florent Hivert wrote:

     Hi Robert,

Copy on write *should* be rather easy to implement for matrices at least.

This is both true and false:

Making the data-structure for having copy-on-write object is fairly easy.
This
is just aving an extra level of indirection and we have something good for that in sage-combinat queue (see [1]). Note that if this patch were be
really
used, it certainly should be Cythonized.

The main problem for COW is a problem of syntax. If obj is a python object
then

  obj1 = obj

makes only a new reference on the *same* object. Unfortunately in Python,
there
is now way to change that like overloading operator::= in C++.

Personally, I think not being able to execute arbitrary code on assignment
is a feature not a bug :)

I more or less agrees with that...

if you want to
make a new *semantic copy* you have to use a different syntax. The way we
tried that in our experiment is

  with obj.mutable(): # obj is now a new semantic copy of itself
                      # copy is done here if needed.
     obj[1] = 1       # in place modifications

The result of the experiment is that, given you have to use this new
syntax,
most of the time if you use it, you really need a *new* copy. The overhead
of
COW is simply not worth it. Therefore we decided that the prototype design pattern was better suitable to our need than COW. Of course, if there was
a
was to overload "=" things were completely different.

My proposal is not to make everything copy on write by default, but rather to make the copy() method lazy. This would be a smaller step, but still useful. In particular, this wouldn't change any current Sage semantics, but would only be an optimization feature. The prototypical use case is when something returns a matrix that's worth caching, but doesn't know if the
user just wants to read it, or might want to modify it.

Well ! I not sure to understand exactly... So you want to return a (semantic) copy of what is cached, right ? So any function returning a matrix (say inverse) will have to explicitely call "return copy(result)". So inverse is
only computed once.

Yes.

But still, do you return a mutable or immutable matrix ?

If you were returning an immutable one, there would be no need to bother with the copy.

Or maybe with this COW you don't want to distinguish anymore ?

I'm fine with still making this distinction. E.g. The original inverse matrix could still be immutable (for safety, in case anyone gets their hands on it).

As for the overhead, one could put the copying code in clear_cache(), and
there would be no need for an extra layer of indirection.

So basically you still want to write

  A = copy(B) # create a semantic copy but no actual copy is done
  A[1,2] = 4  # the copy is triggered...

An since the actual entries of the matrix are stored in an attributes called _entries, two different matrix objects can have share the same entries so that the matrix object is doing the indirection for you. So this sound good and not
very hard to do...

Yep. It's not as transparent as COW on assignment, and happens to be specific to matrices (arguably the most common use) but "explicit is better than implicit."

- Robert

--
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

Reply via email to