Author: Anton Gulenko <[email protected]>
Branch: storage
Changeset: r801:a799759b6a04
Date: 2014-05-06 13:23 +0200
http://bitbucket.org/pypy/lang-smalltalk/changeset/a799759b6a04/

Log:    Added output of strategy statistics as dot-graphs

diff --git a/spyvm/storage_statistics.py b/spyvm/storage_statistics.py
--- a/spyvm/storage_statistics.py
+++ b/spyvm/storage_statistics.py
@@ -99,6 +99,72 @@
             num = tuple[1]
             print "\t%s: %d times, avg size: %f" % (self.key_string(key), num, 
float(sum)/num)
 
+class DotStatisticsCollector(StatisticsCollector):
+    incoming_operations = {}
+    incoming_elements = {}
+    outgoing_operations = {}
+    outgoing_elements = {}
+    def storage_operation(self, key, storage_size, element_classname):
+        StatisticsCollector.storage_operation(self, key, storage_size, 
element_classname)
+        source_type = key[1]
+        target_type = key[2]
+        self.fill_maps(self.incoming_operations, self.incoming_elements, 
target_type, storage_size)
+        if source_type:
+            self.fill_maps(self.outgoing_operations, self.outgoing_elements, 
source_type, storage_size)
+    
+    def fill_maps(self, operations_map, elements_map, key_type, size):
+        if key_type not in operations_map:
+            operations_map[key_type] = 0
+            elements_map[key_type] = 0
+        operations_map[key_type] = operations_map[key_type] + 1
+        elements_map[key_type] = elements_map[key_type] + size
+    
+    def print_result(self):
+        print "Storage Statistics (dot format):"
+        print "================================"
+        print self.dot_string()
+    
+    def dot_string(self):
+               # Unfortunately, this is pretty complicated and messy... Sorry.
+        result = "digraph G {"
+        result += "loading_image [label=\"Image Loading\",shape=box];"
+        result += "created_object [label=\"Object Creation\",shape=box];"
+        for key in self.stats:
+            operation_type = key[0]
+            target_node = key[2]
+            elements = self.stats[key][0]
+            operations = self.stats[key][1]
+            label_suffix = ""
+            if operation_type == "Switched":
+                source_node = key[1]
+                percent_ops = float(operations) / 
float(self.incoming_operations[source_node]) * 100
+                percent_elements = float(elements) / 
float(self.incoming_elements[source_node]) * 100
+                label_suffix = "\n%0.2f%% objects\n%0.2f%% elements" % 
(percent_ops, percent_elements)
+            elif operation_type == "Initialized":
+                source_node = "created_object"
+            elif operation_type == "Filledin":
+                source_node = "loading_image"
+            else:
+                print "Could not handle storage operation %s" % operation_type
+                continue
+            result += "%s -> %s [label=\"%d (avg %0.2f)%s\"];" % (source_node, 
target_node, operations, float(elements)/float(operations), label_suffix)
+        for type in self.incoming_operations:
+            incoming_ops = self.incoming_operations[type]
+            incoming_els = self.incoming_elements[type]
+            label = "\nIncoming objects: %d" % incoming_ops
+            label += "\nIncoming elements: %d" % incoming_els
+            if type in self.outgoing_operations:
+                remaining_ops = incoming_ops - self.outgoing_operations[type]
+                remaining_els = incoming_els - self.outgoing_elements[type]
+            else:
+                remaining_ops = incoming_ops
+                remaining_els = incoming_els
+            label += "\nRemaining objects: %d (%0.2f%%)" % (remaining_ops, 
float(remaining_ops)/incoming_ops*100)
+            label += "\nRemaining elements: %d (%0.2f%%)" % (remaining_els, 
float(remaining_els)/incoming_els*100)
+            result += "%s [label=\"%s%s\"];" % (type, type, label)
+        result += "}"
+        return result
+    
 class DetailedStatisticsCollector(AbstractStatisticsCollector):
     # Value: list of numbers (sizes)
     def initial_value(self): return []
@@ -115,14 +181,17 @@
 _logger = StatisticsLogger()
 _collector = StatisticsCollector()
 _detailedcollector = DetailedStatisticsCollector()
+_dotcollector = DotStatisticsCollector()
 
-def activate_statistics(log=False, statistics=False, 
detailed_statistics=False):
+def activate_statistics(log=False, statistics=False, 
detailed_statistics=False, dot=False):
     if log:
         _stats.add_module(_logger)
     if statistics:
         _stats.add_module(_collector)
     if detailed_statistics:
         _stats.add_module(_detailedcollector)
+    if dot:
+        _stats.add_module(_dotcollector)
 
 def print_statistics():
     _stats.print_results()
diff --git a/spyvm/test/test_strategies.py b/spyvm/test/test_strategies.py
--- a/spyvm/test/test_strategies.py
+++ b/spyvm/test/test_strategies.py
@@ -177,8 +177,8 @@
     check_arr(a, [1.2, 2, w_nil, w_nil, w_nil])
 
 def test_statistics_stats():
+    col = storage_statistics.DetailedStatisticsCollector()
     stats = storage_statistics.StorageStatistics()
-    col = storage_statistics.DetailedStatisticsCollector()
     col.storage_operation(stats.make_key("B", "old", "new"), 3, None)
     col.storage_operation(stats.make_key("B", "old", "new"), 4, None)
     col.storage_operation(stats.make_key("B", "old2", "new2"), 20, None)
@@ -201,4 +201,22 @@
     assert s == "Operation (old_storage -> new_storage) of classname size 22"
     s = log.log_string(stats.make_key("InitialOperation", None, 
"some_new_storage"), 40, "a_classname")
     assert s == "InitialOperation (some_new_storage) of a_classname size 40"
+    
+def test_statistics_stats_dot():
+    col = storage_statistics.DotStatisticsCollector()
+    stats = storage_statistics.StorageStatistics()
+    
+    col.storage_operation(stats.make_key("Switched", "old", "new"), 10, None)
+    col.storage_operation(stats.make_key("Switched", "old", "new"), 10, None)
+    col.storage_operation(stats.make_key("Switched", "new", "new2"), 10, None)
+    col.storage_operation(stats.make_key("Switched", "old2", "new"), 5, None)
+    col.storage_operation(stats.make_key("Initialized", None, "old"), 13, None)
+    col.storage_operation(stats.make_key("Initialized", None, "old"), 10, None)
+    col.storage_operation(stats.make_key("Initialized", None, "old"), 10, None)
+    col.storage_operation(stats.make_key("Initialized", None, "old2"), 15, 
None)
+    col.storage_operation(stats.make_key("Filledin", None, "old2"), 20, None)
+    col.storage_operation(stats.make_key("Filledin", None, "new"), 10, None)
+    col.storage_operation(stats.make_key("Filledin", None, "new"), 11, None)
+    
+    assert col.dot_string() == ""
     
\ No newline at end of file
diff --git a/targetimageloadingsmalltalk.py b/targetimageloadingsmalltalk.py
--- a/targetimageloadingsmalltalk.py
+++ b/targetimageloadingsmalltalk.py
@@ -189,6 +189,8 @@
             storage_statistics.activate_statistics(log=True)
         elif arg == "--strategy-stats":
             storage_statistics.activate_statistics(statistics=True)
+        elif arg == "--strategy-stats-dot":
+            storage_statistics.activate_statistics(dot=True)
         elif arg == "--strategy-stats-details":
             storage_statistics.activate_statistics(statistics=True, 
detailed_statistics=True)
         elif path is None:
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to