1   /****************************************************************************
2    * This demo file is part of yFiles for Java 2.14.
3    * Copyright (c) 2000-2017 by yWorks GmbH, Vor dem Kreuzberg 28,
4    * 72070 Tuebingen, Germany. All rights reserved.
5    * 
6    * yFiles demo files exhibit yFiles for Java functionalities. Any redistribution
7    * of demo files in source code or binary form, with or without
8    * modification, is not permitted.
9    * 
10   * Owners of a valid software license for a yFiles for Java version that this
11   * demo is shipped with are allowed to use the demo source code as basis
12   * for their own yFiles for Java powered applications. Use of such programs is
13   * governed by the rights and conditions as set out in the yFiles for Java
14   * license agreement.
15   * 
16   * THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESS OR IMPLIED
17   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18   * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
19   * NO EVENT SHALL yWorks BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
21   * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22   * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23   * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24   * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25   * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26   *
27   ***************************************************************************/
28  package demo.base;
29  
30  import java.util.HashMap;
31  import java.util.Map;
32  import y.util.Maps;
33  import y.util.Timer;
34  import y.util.D;
35  import y.base.Graph;
36  import y.base.NodeMap;
37  import y.base.NodeCursor;
38  import y.base.Node;
39  
40  
41  /**
42   * This class compares the performance of different 
43   * mechanisms to bind extra data to the nodes of a graph.
44   * In scenarios where the indices of the nodes do not change
45   * while the extra node data is needed, it is best to use array based
46   * mechanisms that use the index of a node to access the data.
47   * <br>
48   * In scenarios where the indices of the nodes will change
49   * while the extra node data is needed, it is necessary to
50   * use {@link y.base.NodeMap} implementations that do not depend on the indices
51   * of the nodes (see {@link Node#index()}) or {@link java.util.Map}
52   * implementations like {@link java.util.HashMap} provided by the java
53   * collections framework.
54   *
55   * @see <a href="http://docs.yworks.com/yfiles/doc/api/index.html#/dguide/data_accessors#Maps and Data Providers" target="_blank">Section Maps and Data Providers</a> in the yFiles for Java Developer's Guide
56   */
57  public class NodeMapTest
58  {
59    
60    static Timer t1 = new Timer(false);
61    static Timer t2 = new Timer(false);
62    static Timer t3 = new Timer(false);
63    static Timer t4 = new Timer(false);
64    static Timer t5 = new Timer(false);
65    
66    public static void main(String[] args)
67    {
68      test1();
69    }
70    
71    static void test1()
72    {
73      Graph graph = new Graph();
74      for(int i = 0; i < 20000; i++) graph.createNode();
75      
76      for(int loop = 0; loop < 10; loop++)
77      {
78        D.bu(".");
79        
80        t1.start();
81        NodeMap map = graph.createNodeMap();
82        for(int i = 0; i < 10; i++)
83        {
84          for(NodeCursor nc = graph.nodes(); nc.ok(); nc.next())
85          {
86            Node v = nc.node();
87            map.setInt(v,i);
88            i = map.getInt(v);
89          }
90        }
91        graph.disposeNodeMap(map);
92        t1.stop();
93        
94        
95        t2.start();
96        map = Maps.createIndexNodeMap(new int[graph.N()]);
97        for(int i = 0; i < 10; i++)
98        {
99          for(NodeCursor nc = graph.nodes(); nc.ok(); nc.next())
100         {
101           Node v = nc.node();
102           map.setInt(v,i);
103           map.getInt(v);
104         }
105       }
106       t2.stop();
107       
108       
109       t3.start();
110       map = Maps.createHashedNodeMap(); 
111       for(int i = 0; i < 10; i++)
112       {
113         for(NodeCursor nc = graph.nodes(); nc.ok(); nc.next())
114         {
115           Node v = nc.node();
116           map.setInt(v, i);
117           i = map.getInt(v);
118         }
119       }
120       t3.stop();
121       
122       t4.start();
123       int[] array = new int[graph.N()];
124       for(int i = 0; i < 10; i++)
125       {
126         for(NodeCursor nc = graph.nodes(); nc.ok(); nc.next())
127         {
128           int vid = nc.node().index();
129           array[vid] = i;
130           i = array[vid];
131         }
132       }
133       t4.stop();
134 
135     
136       t5.start();
137       Map jmap = new HashMap(2*graph.N()+1); //use hash map with good initial size
138       for(int i = 0; i < 10; i++)
139       {
140         for(NodeCursor nc = graph.nodes(); nc.ok(); nc.next())
141         {
142           Node v = nc.node();
143           jmap.put(v, new Integer(i));
144           i = ((Integer)jmap.get(v)).intValue();
145         }
146       }
147       t5.stop();
148       
149     }
150     
151     D.bug("");
152     D.bug("TIME:  standard NodeMap: " + t1);
153     D.bug("TIME:  index    NodeMap: " + t2);
154     D.bug("TIME:  hashed   NodeMap: " + t3);
155     D.bug("TIME:  plain array     : " + t4);
156     D.bug("TIME:  HashMap         : " + t5);
157   }
158 }
159 
160     
161     
162     
163