<!DOCTYPE article PUBLIC "-//NLM//DTD JATS (Z39.96) Journal Archiving and Interchange DTD v1.0 20120330//EN" "JATS-archivearticle1.dtd">
<article xmlns:xlink="http://www.w3.org/1999/xlink">
  <front>
    <journal-meta />
    <article-meta>
      <title-group>
        <article-title>A proposal to improve performance of ATL collections</article-title>
      </title-group>
      <contrib-group>
        <contrib contrib-type="author">
          <string-name>Jesoes S</string-name>
          <xref ref-type="aff" rid="aff0">0</xref>
        </contrib>
        <contrib contrib-type="author">
          <string-name>nchez Cuadrado</string-name>
          <xref ref-type="aff" rid="aff0">0</xref>
        </contrib>
        <aff id="aff0">
          <label>0</label>
          <institution>University of Murcia</institution>
        </aff>
      </contrib-group>
      <abstract>
        <p>This paper presents a proposal to replace the current implementation of collections in the ATL-VM (based on the Java collection library) with a new implementation that supports inmutable collections natively. A rst prototype using the Clojure collection library has been implemented, and some performance results from benchmarks has been gathered. They show that the proposal has the potential to improve performance signicantly.</p>
      </abstract>
    </article-meta>
  </front>
  <body>
    <sec id="sec-1">
      <title>Introduction</title>
    </sec>
    <sec id="sec-2">
      <title>Problem description</title>
      <p>Current implementation of the ATL-VM provides several native collection datatypes.
They correspond to the ones of the OCL specication (Sequence, Bag, Set,
OrderedSet) plus a datatype for associative tables (Map).</p>
      <p>Collection operations are inmutable, that is, they never change the original
collection. Basic operations like includes, including, union are implemented
directly by the ATL-VM. On the contrary, operations that takes an iterator
expression are implemented by the ATL compiler. For instance, the select
operation is compiled as follows (in pseudo-code):
result = new Sequence
iterate o &lt;- collection
v = evaluate iterator-expr(o)
if v</p>
      <p>result = result.including(o)
end
enditerate</p>
      <p>The performance problem arises when the actual implementation of the
update operations is considered. The ATL-VM rely on the Java collection library,
whose update operations are mutable, to implement inmutable update
operations. This mismatch makes every update operation do a complete copy of the
original collection for each call, and then modify the copy.</p>
      <p>In the case of the select operation shown above, the result collection is
copied each time an element is selected.</p>
      <p>
        A solution, pointed out in [
        <xref ref-type="bibr" rid="ref2">2</xref>
        ], is to add mutable versions of update operations
to the VM, and let the compiler decide when it is safe to use them. For instance,
there is an important performance improvement if a mutable version of the
including operation is used to implement the select operation. However, the
drawback of this approach is that the ATL compiler must be changed. Some of
the changes would be straightforward, but there are cases that require specialized
analysis. Moreover, existing transformation denitions should be recompiled.
3
      </p>
    </sec>
    <sec id="sec-3">
      <title>Proposal</title>
      <p>
        To tackle the issues presented in the previous section, we have replaced the
Java collections library (in the ATL-VM) with a library implementing inmutable
collections. In particular, we have reused the implementation provided by
Clojure [
        <xref ref-type="bibr" rid="ref1">1</xref>
        ], a functional language for the JVM. It eciently deals with update
operations for inmutable collections (see [
        <xref ref-type="bibr" rid="ref4">4</xref>
        ][
        <xref ref-type="bibr" rid="ref3">3</xref>
        ] for more information).
      </p>
      <p>We propose the following mapping between OCL/ATL datatypes and Clojure
classes:</p>
      <p>ATL
Sequence</p>
      <p>Bag</p>
      <p>Set
OrderedSet</p>
      <p>Map</p>
      <p>Clojure
PersistentVector</p>
      <p>PersistentList
PersistentHashSet
PersistentTreeSet</p>
      <p>PersistentHashMap
The mapping is simple, since Clojure collection library provides datatypes similar
to that of OCL. There is however an issue with sequences. At rst sight, a list
would be the proper mapping, but the main update operation for lists in Clojure
(like in Lisp) is cons, which returns a new list where the new element is the rst
one and the original list is the rest. This is why OCL Sequences are mapped to
Clojure vectors, which add elements to the end of the collection. This has an
slight impact in performance, as will be shown in next section.</p>
      <p>Implementing a rst prototype that is able to execute basic operations has
been relatively straightforward. Two Java classes were modied, OclType and
ExecEnv. The former establish a mapping between OCL types and Java classes
implementing them, while the latter contains the implementation of the
operations of each type. These were the only two classes that had to be modied.</p>
      <p>However, there were two issues that hindered the implementation:
1. Datatype instantiation . In Clojure, an empty collection is actually a constant.</p>
      <p>However, the mapping between OCL types and Java classes requires setting
the name of Java class that will be instantiated each time. A wrapper class
for empty collections has been created, but this has required duplicating the
operations code in ExecEnv.
2. Operation mapping . There is not a one-to-one mapping between OCL
collection operations and Clojure operations. For instance, in Clojure collection
concatenation (union in OCL) is not implemented in Java code but in
Clojure’s. Thus, only a part of the Clojure library can be reused, the rest has
to be implemented from scratch in Java.
4</p>
    </sec>
    <sec id="sec-4">
      <title>Benchmarks</title>
      <p>This section presents a couple of results from the performance benchmarks we
have carried out. While they are simple (more or less synthetic) benchmarks,
they conrm our insight that implementing true inmutable collections in the
ATL-VM will improve the performance of ATL transformations.</p>
      <p>Each benchmark measures performance of the ATL-VM (EMF-VM) without
any modication, against a modied version which uses mutable operations (it
is unsafe, not usable in a real context), and against the a modied VM that uses
Clojure collections.
4.1</p>
      <p>Sequence
The benchmark for the including operation consists of iterating over an OCL
sequence of n elements, adding the current element to another sequence in each
iteration step. The execution time for dierent input sizes is shown in Figure 1.</p>
      <p>As can be seen, in the the current version of the VM including does not
scale well (i.e. time doesn’t grow linearly with respect to the model size). On
the contrary, execution time using the other three versions grows linearly.
Interestingly, performance of PersistentList is comparable to using a mutable list.
Anyway, as explained, this is not a proper choice to implement OCL sequences
because of the semantics of cons. Performance of PersistentVector is slightly
worse, but still better than the current implementation.
4.2</p>
      <p>Map
The performance benchmark for Map has consisted on implementing a simple
matching algorithm. It takes as input a model containing the same number of
elements A and B, randomly ordered. For each element A, the corresponding
matching element B is found (comparing the value of an attribute). The source
model ensures that there is one and only one matching element B for each element
A. At the beginning of the transformation all matches are computed and stored
in map. Applying a similar algorithm is needed in some model weaving problems.</p>
      <p>Again, the current version of the VM does not scale well because of the
need to copy the whole map for each update. Both alternative versions improve
performance. Moreover the performance of PersistentMap is comparable to the
unsafe version.
5</p>
    </sec>
    <sec id="sec-5">
      <title>Conclusion</title>
      <p>In the paper, we have presented a proposal to improve performance of collections
in ATL. It has been compared to other two alternatives (current version of the
ATL-VM and modifying the ATL compiler to support mutable operations). It
does not require any change to the ATL compiler, and therefore will not require
re-compiling existing ATL programs, because it is only a change in the VM.</p>
      <p>The initial results shows that our prototype, based on the Clojure collection
library, outperforms the current ATL-VM. This suggests that it is worth the
eort of implementing a complete solution based on true inmutable collections
(probably implementing a specic collection library for the ATL-VM).
0.45
0.4
0.35
0.1
0.05</p>
      <p>0
4.5
3.5
0.5
Normal
Mutable</p>
      <p>ClojureVector
ClojureSequence</p>
      <p>Benchmark - including</p>
    </sec>
  </body>
  <back>
    <ref-list>
      <ref id="ref1">
        <mixed-citation>
          1.
          <article-title>Clojure programming language</article-title>
          . http://clojure.org/.
        </mixed-citation>
      </ref>
      <ref id="ref2">
        <mixed-citation>
          2.
          <string-name>
            <given-names>J. S.</given-names>
            <surname>Cuadrado</surname>
          </string-name>
          ,
          <string-name>
            <given-names>F.</given-names>
            <surname>Jouault</surname>
          </string-name>
          ,
          <string-name>
            <given-names>J.</given-names>
            <surname>Garcia-Molina</surname>
          </string-name>
          ,
          <article-title>and</article-title>
          <string-name>
            <surname>J. BŁzivin.</surname>
          </string-name>
          <article-title>Optimization patterns for OCL-based model transformations</article-title>
          .
          <source>In Proceedings of the 8th OCL Workshop</source>
          ,
          <year>2008</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref3">
        <mixed-citation>
          3.
          <string-name>
            <given-names>K.</given-names>
            <surname>Krukow</surname>
          </string-name>
          .
          <article-title>Clojure hash-map implementation</article-title>
          . http://blog.higherorder.net/
          <year>2009</year>
          /09/08/understanding-clojures
          <string-name>
            <surname>-</surname>
          </string-name>
          persistenthashmap-deftwice/.
        </mixed-citation>
      </ref>
      <ref id="ref4">
        <mixed-citation>
          4.
          <string-name>
            <given-names>K.</given-names>
            <surname>Krukow</surname>
          </string-name>
          .
          <article-title>Clojure vector implementation</article-title>
          . http://blog.higherorder.net/
          <year>2009</year>
          /02/01/understanding-clojures
          <string-name>
            <surname>-</surname>
          </string-name>
          persistentvector-implementation.
          <source>2000 4000 8000 16000 Model size (number of elements) 32000 1000 2500 5000 Model size (number of elements)</source>
        </mixed-citation>
      </ref>
    </ref-list>
  </back>
</article>