octave-maintainers
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

thoughts about element access


From: Jaroslav Hajek
Subject: thoughts about element access
Date: Mon, 24 Nov 2008 12:19:23 +0100

When thinking about redesigning somewhat the Array classes in
liboctave, I stumbled upon the following issue:
The current copy-on-write mechanism forces unnecessary copies.

Consider, for instance, a DLD function written by a naive user like this

DEFUN_DLD(trace,args,,"")
{
    Matrix x = args(0).matrix_value ();
    double res = 0;
    for (octave_idx_type i = 0; i < x.rows (); i++)
      res += x(i,i);

   return octave_value (res);
}

Now, you may be surprised that this may actually be *less* efficient
than coding the same function as an m-file.
The reason is that `x' is declared as "Matrix" rather than "const
Matrix", and, therefore, the call x(i,i) calls Array<T>::make_unique
which forces a copy (there is at least one shared copy of x inside
args(0)). The problem is that the () operator is overloaded
for *both* const and non-const version, thus there the compiler sees
no reason to add the missing const qualifier.

One option is to simply ignore this. The situation is not at all that
bad; mostly, matrices supposed to be read-only are passed as const
arguments.
There are a couple of places in Octave that probably suffer from this
effect, I think most of these can be fixed by adding "const" where
appropriate.
The drawback is that this effect is fairly quirky - those who don't
understand the internals of Octave will inevitably tend to code this
way. If we want an
official API, I think such effects are undesirable.

The alternative is to make Array<T>::operator () return a special
"proxy" object that would support casting/assignment to/from T. This
proxy object would only uniquify the Array when necessary (i.e. whan
an assignment is made into the proxy). This approach is already used
for DiagArray2.
The main drawback is, of course, that Proxy is not a true reference to
T, so that things like x(i,j)++ or ~x(i,j) are not automatically
available.
Certainly we can overload the proxy to support the common operators
for common types, but the problem will remain for classes. Since
instantiating Array<T>for user classes is mostly undesirable anyway
(unless you need the slicing methods), I think this is not such a
problem, but still...
Another drawback is that code would need to be changed (no big deal)
and even this problem should be explained in the API documentation.

Btw. When using proxies, it would be easy to also support subscripting
by idx_vectors.


opinions? Which approach would you prefer?


-- 
RNDr. Jaroslav Hajek
computing expert
Aeronautical Research and Test Institute (VZLU)
Prague, Czech Republic
url: www.highegg.matfyz.cz


reply via email to

[Prev in Thread] Current Thread [Next in Thread]