1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<!-- Created by GNU Texinfo 5.2, http://www.gnu.org/software/texinfo/ -->
<head>
<title>GNU Octave: Indexed Assignment Optimization</title>
<meta name="description" content="GNU Octave: Indexed Assignment Optimization">
<meta name="keywords" content="GNU Octave: Indexed Assignment Optimization">
<meta name="resource-type" content="document">
<meta name="distribution" content="global">
<meta name="Generator" content="makeinfo">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link href="index.html#Top" rel="start" title="Top">
<link href="Concept-Index.html#Concept-Index" rel="index" title="Concept Index">
<link href="index.html#SEC_Contents" rel="contents" title="Table of Contents">
<link href="Indexing-Objects.html#Indexing-Objects" rel="up" title="Indexing Objects">
<link href="Overloading-Objects.html#Overloading-Objects" rel="next" title="Overloading Objects">
<link href="Defining-Indexing-And-Indexed-Assignment.html#Defining-Indexing-And-Indexed-Assignment" rel="prev" title="Defining Indexing And Indexed Assignment">
<style type="text/css">
<!--
a.summary-letter {text-decoration: none}
blockquote.smallquotation {font-size: smaller}
div.display {margin-left: 3.2em}
div.example {margin-left: 3.2em}
div.indentedblock {margin-left: 3.2em}
div.lisp {margin-left: 3.2em}
div.smalldisplay {margin-left: 3.2em}
div.smallexample {margin-left: 3.2em}
div.smallindentedblock {margin-left: 3.2em; font-size: smaller}
div.smalllisp {margin-left: 3.2em}
kbd {font-style:oblique}
pre.display {font-family: inherit}
pre.format {font-family: inherit}
pre.menu-comment {font-family: serif}
pre.menu-preformatted {font-family: serif}
pre.smalldisplay {font-family: inherit; font-size: smaller}
pre.smallexample {font-size: smaller}
pre.smallformat {font-family: inherit; font-size: smaller}
pre.smalllisp {font-size: smaller}
span.nocodebreak {white-space:nowrap}
span.nolinebreak {white-space:nowrap}
span.roman {font-family:serif; font-weight:normal}
span.sansserif {font-family:sans-serif; font-weight:normal}
ul.no-bullet {list-style: none}
-->
</style>
</head>
<body lang="en" bgcolor="#FFFFFF" text="#000000" link="#0000FF" vlink="#800080" alink="#FF0000">
<a name="Indexed-Assignment-Optimization"></a>
<div class="header">
<p>
Previous: <a href="Defining-Indexing-And-Indexed-Assignment.html#Defining-Indexing-And-Indexed-Assignment" accesskey="p" rel="prev">Defining Indexing And Indexed Assignment</a>, Up: <a href="Indexing-Objects.html#Indexing-Objects" accesskey="u" rel="up">Indexing Objects</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Concept-Index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
</div>
<hr>
<a name="Indexed-Assignment-Optimization-1"></a>
<h4 class="subsection">34.3.2 Indexed Assignment Optimization</h4>
<p>Octave’s ubiquitous lazily-copied pass-by-value semantics implies
a problem for performance of user-defined subsasgn methods. Imagine
a call to subsasgn:
</p>
<div class="example">
<pre class="example"> ss = substruct ("()",{1});
x = subsasgn (x, ss, 1);
</pre></div>
<p>and the corresponding method looking like this:
</p>
<div class="example">
<pre class="example"> function x = subsasgn (x, ss, val)
…
x.myfield (ss.subs{1}) = val;
endfunction
</pre></div>
<p>The problem is that on entry to the subsasgn method, <code>x</code> is still
referenced from the caller’s scope, which means that the method will
first need to unshare (copy) <code>x</code> and <code>x.myfield</code> before performing
the assignment. Upon completing the call, unless an error occurs,
the result is immediately assigned to <code>x</code> in the caller’s scope,
so that the previous value of <code>x.myfield</code> is forgotten. Hence, the
Octave language implies a copy of N elements (N being the size of
<code>x.myfield</code>), where modifying just a single element would actually
suffice, i.e., degrades a constant-time operation to linear-time one.
This may be a real problem for user classes that intrinsically store large
arrays.
</p>
<p>To partially solve the problem, Octave uses a special optimization for
user-defined subsasgn methods coded as m-files. When the method
gets called as a result of the built-in assignment syntax (not direct subsasgn
call as shown above), i.e.
</p>
<div class="example">
<pre class="example"> x(1) = 1;
</pre></div>
<p><b>AND</b> if the subsasgn method is declared with identical input and output argument,
like in the example above, then Octave will ignore the copy of <code>x</code> inside
the caller’s scope; therefore, any changes made to <code>x</code> during the method
execution will directly affect the caller’s copy as well.
This allows, for instance, defining a polynomial class where modifying a single
element takes constant time.
</p>
<p>It is important to understand the implications that this optimization brings.
Since no extra copy of <code>x</code> in the caller’s scope will exist, it is
<em>solely</em> the callee’s responsibility to not leave <code>x</code> in an invalid
state if an error occurs throughout the execution. Also, if the method
partially changes <code>x</code> and then errors out, the changes <em>will</em> affect
<code>x</code> in the caller’s scope. Deleting or completely replacing <code>x</code>
inside subsasgn will not do anything, however, only indexed assignments matter.
</p>
<p>Since this optimization may change the way code works (especially if badly
written), a built-in variable <code>optimize_subsasgn_calls</code> is provided to
control it. It is on by default. Another option to avoid the effect is to
declare subsasgn methods with different output and input arguments, like this:
</p>
<div class="example">
<pre class="example"> function y = subsasgn (x, ss, val)
…
endfunction
</pre></div>
<hr>
<div class="header">
<p>
Previous: <a href="Defining-Indexing-And-Indexed-Assignment.html#Defining-Indexing-And-Indexed-Assignment" accesskey="p" rel="prev">Defining Indexing And Indexed Assignment</a>, Up: <a href="Indexing-Objects.html#Indexing-Objects" accesskey="u" rel="up">Indexing Objects</a> [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Concept-Index.html#Concept-Index" title="Index" rel="index">Index</a>]</p>
</div>
</body>
</html>
|