From 27438f60e4bd01af949d9e6a6c98a98b4737ea10 Mon Sep 17 00:00:00 2001
From: hjk <qtc-committer@nokia.com>
Date: Tue, 20 Sep 2011 17:50:45 +0200
Subject: [PATCH] add some example with statistics on the impact of using small
 classes

Change-Id: I29c68ce88fef599091a84f8bdec54778e4d62b03
Reviewed-on: http://codereview.qt-project.org/5257
Reviewed-by: hjk <qthjk@ovi.com>
---
 doc/api/examples/aggregation/README     |  21 +++
 doc/api/examples/aggregation/output.txt |  35 +++++
 doc/api/examples/aggregation/test.sh    | 196 ++++++++++++++++++++++++
 3 files changed, 252 insertions(+)
 create mode 100644 doc/api/examples/aggregation/README
 create mode 100644 doc/api/examples/aggregation/output.txt
 create mode 100755 doc/api/examples/aggregation/test.sh

diff --git a/doc/api/examples/aggregation/README b/doc/api/examples/aggregation/README
new file mode 100644
index 00000000000..8e67b605543
--- /dev/null
+++ b/doc/api/examples/aggregation/README
@@ -0,0 +1,21 @@
+
+Running test.sh tests several replacement patterns for a typical case
+of polymorphism, and creates some statistics of the output.
+
+The 'critical' case is where the implementation is only instantiated
+from a single location.
+
+'Symbols' refers to the number of additional symbols created by the
+pattern (relevant for relocation on application startup and debugger
+performance)
+
+'Size' refers to the size of the '.text' section, i.e. the 'generated
+code'.
+
+'Debug' is the size of the .debug_info section in the binary.
+
+
+Note that the numbers are not directly comparable. As the 'Slim'
+versions push code from the implementation to the user side, the
+ratio will be "better" when the the implementation is instantiated
+from more than one place.
diff --git a/doc/api/examples/aggregation/output.txt b/doc/api/examples/aggregation/output.txt
new file mode 100644
index 00000000000..6b75ec188d5
--- /dev/null
+++ b/doc/api/examples/aggregation/output.txt
@@ -0,0 +1,35 @@
+Interface/Implementation (out of line)
+
+Symbols:  13
+Size:     2388	  
+Debug:    4541
+
+
+Interface/Implementation (non-virtual)
+
+Symbols:  13
+Size:     2388	  
+Debug:    4431
+
+
+Interface/Implementation (inline)
+
+Symbols:  12
+Size:     2643	  
+Debug:    4402
+
+
+Merged
+
+Symbols:  7
+Size:     2447	  
+Debug:    4342
+
+
+Slimmest possible
+
+Symbols:  0
+Size:     1971	  
+Debug:    4246
+
+
diff --git a/doc/api/examples/aggregation/test.sh b/doc/api/examples/aggregation/test.sh
new file mode 100755
index 00000000000..5232ce8629a
--- /dev/null
+++ b/doc/api/examples/aggregation/test.sh
@@ -0,0 +1,196 @@
+#!/bin/bash
+
+export CXX="g++ -O3 -g "
+
+function stat() {
+    echo -e ""
+    echo -e "Symbols:  $(nm $@ | grep ' [TVW] ' | grep _Z | grep -v "_ZNSs" | wc -l)"
+    echo -e "Size:  $(size -d -B $@ | tail -1 | cut -c1-10)"
+    echo -e "Debug:    $(echo "ibase=16;"$(readelf -S $@ | grep debug_info | cut -c50-56 | tr a-f A-F) | bc)"
+    echo -e ""
+    echo -e ""
+#    echo -e "Symbols: $(nm "$@" | grep ' [TUVW] '|  grep _Z )"
+}
+
+
+function test_1() {
+
+echo "Interface/Implementation (out of line)"
+
+cat > interface_1.h <<EOF
+#include <string>
+struct Interface { virtual ~Interface() {} virtual std::string func() const = 0; };
+EOF
+
+cat > implementation_1.h <<EOF
+#include "interface_1.h"
+struct Implementation : Interface { std::string func() const; };
+EOF
+
+cat > implementation_1.cpp <<EOF
+#include "implementation_1.h"
+std::string Implementation::func() const { return "Test1"; }
+EOF
+
+cat > main_1.cpp <<EOF
+#include "implementation_1.h"
+int main() { Interface *x = new Implementation(); return x->func().size(); }
+EOF
+
+$CXX implementation_1.cpp main_1.cpp -o test_1
+stat test_1
+
+}
+
+
+function test_2() {
+
+echo "Interface/Implementation (non-virtual)"
+
+cat > interface_2.h <<EOF
+#include <string>
+struct Interface { virtual ~Interface() {} virtual std::string func() const = 0; };
+EOF
+
+cat > implementation_2.h <<EOF
+#include "interface_2.h"
+struct Implementation : Interface {
+    ~Implementation() {} std::string func() const { return "Test2"; } };
+EOF
+
+cat > main_2.cpp <<EOF
+#include "implementation_2.h"
+int main() { Interface *x = new Implementation(); return x->func().size(); }
+EOF
+
+$CXX main_2.cpp -o test_2
+stat test_2
+
+}
+
+
+function test_3() {
+
+echo "Interface/Implementation (inline)"
+
+cat > interface_3.h <<EOF
+#include <string>
+struct Interface
+{
+    virtual ~Interface() {}
+    std::string func() const { return m_data; }
+    std::string m_data;
+};
+EOF
+
+cat > implementation_3.h <<EOF
+#include "interface_3.h"
+struct Implementation : Interface {
+    Implementation() { m_data = "Test3"; }
+};
+EOF
+
+cat > main_3.cpp <<EOF
+#include "implementation_3.h"
+int main() { Interface *x = new Implementation(); return x->func().size(); }
+EOF
+
+$CXX main_3.cpp -o test_3
+stat test_3
+
+}
+
+
+function test_4() {
+
+echo "Merged"
+
+cat > interface_4.h <<EOF
+#include <string>
+struct Interface
+{
+    virtual ~Interface() {}
+    std::string func() const { return m_data; }
+    void setData(const std::string &data) { m_data = data; }
+private:
+    std::string m_data;
+};
+EOF
+
+cat > implementation_4.h <<EOF
+#include "interface_4.h"
+void setupImplementation(Interface *i) { i->setData("Test4"); }
+EOF
+
+cat > main_4.cpp <<EOF
+#include "implementation_4.h"
+int main() { Interface *x = new Interface(); setupImplementation(x); return x->func().size(); }
+EOF
+
+$CXX main_4.cpp -o test_4
+stat test_4
+
+}
+
+
+function test_5() {
+
+echo "Slimmest possible"
+
+cat > interface_5.h <<EOF
+#include <string>
+struct Interface
+{
+    std::string func() const { return m_data; }
+    void setData(const std::string &data) { m_data = data; }
+private:
+    std::string m_data;
+};
+EOF
+
+cat > main_5.cpp <<EOF
+#include "interface_5.h"
+int main() { Interface *x = new Interface(); x->setData("Test4"); return x->func().size(); }
+EOF
+
+$CXX main_5.cpp -o test_5
+stat test_5
+
+}
+
+
+function test_6() {
+
+echo "Constructor"
+
+cat > interface_6.h <<EOF
+#include <string>
+struct Interface
+{
+    explicit Interface(const std::string &data) : m_data(data) {}
+    std::string func() const { return m_data; }
+private:
+    const std::string m_data;
+};
+EOF
+
+cat > main_6.cpp <<EOF
+#include "interface_6.h"
+int main() { Interface *x = new Interface("Test4"); return x->func().size(); }
+EOF
+
+$CXX main_6.cpp -o test_6
+stat test_6
+
+}
+
+function main() {
+    test_1
+    test_2
+    test_3
+    test_4
+    test_5
+    #test_6
+}
+
+main
-- 
GitLab