Author: Antonio Cuni <[email protected]>
Branch: extradoc
Changeset: r5535:60dd04fca106
Date: 2015-04-17 13:10 +0200
http://bitbucket.org/pypy/extradoc/changeset/60dd04fca106/

Log:    more slides

diff --git a/talk/pycon-italy-2015/src/decode2.py 
b/talk/pycon-italy-2015/src/decode2.py
new file mode 100644
--- /dev/null
+++ b/talk/pycon-italy-2015/src/decode2.py
@@ -0,0 +1,42 @@
+import sys
+import struct
+
+P1 = '\x0c\x00\x00\x00"\x00\x00\x00\x07\x00'
+P2 = '\x15\x00\x00\x00+\x00\x00\x00\x08\x00'
+
+PLIST = [P1, P2] * 2000
+
+class Field(object):
+
+    def __init__(self, fmt, offset):
+        self.fmt = fmt
+        self.offset = offset
+
+def Message(name, fields):
+    class M(object):
+        def read(self, buf, name):
+            f = getattr(self, name)
+            return struct.unpack_from(f.fmt, buf, f.offset)[0]            
+
+    for fname, f in fields.iteritems():
+        setattr(M, fname, f)
+
+    M.__name__ = name
+    return M()
+
+
+Point = Message('Point', {
+    'x': Field('l', 0),
+    'y': Field('l', 4),
+    'color': Field('i', 8)
+    })
+
+
+def main():
+    res = 0
+    for p in PLIST:
+        x = Point.read(p, 'x')
+        res += x
+    print res
+
+main()
diff --git a/talk/pycon-italy-2015/src/decode3.py 
b/talk/pycon-italy-2015/src/decode3.py
new file mode 100644
--- /dev/null
+++ b/talk/pycon-italy-2015/src/decode3.py
@@ -0,0 +1,32 @@
+import sys
+import struct
+
+P1 = '\x0c\x00\x00\x00"\x00\x00\x00\x07\x00'
+P2 = '\x15\x00\x00\x00+\x00\x00\x00\x08\x00'
+
+PLIST = [P1, P2] * 2000
+
+class Field(object):
+    def __init__(self, fmt, offset):
+        self.fmt = fmt
+        self.offset = offset
+
+    def __get__(self, obj, cls):
+        return struct.unpack_from(self.fmt, obj._buf, self.offset)[0]
+
+class Point(object):
+    def __init__(self, buf):
+        self._buf = buf
+
+    x = Field('l', 0)
+    y = Field('l', 4)
+    color = Field('h', 8)
+
+def main():
+    res = 0
+    for p in PLIST:
+        p = Point(p)
+        res += p.x
+    print res
+
+main()
diff --git a/talk/pycon-italy-2015/talk.rst b/talk/pycon-italy-2015/talk.rst
--- a/talk/pycon-italy-2015/talk.rst
+++ b/talk/pycon-italy-2015/talk.rst
@@ -244,9 +244,9 @@
 .. sourcecode:: C
 
     struct Point {
-        long x;
-        long y;
-        int color;
+        int x;
+        int y;
+        short color;
     }
 
 |end_example|
@@ -433,6 +433,121 @@
 |end_example|
 |end_scriptsize|
 
+Example: faster API
+---------------------
+
+|scriptsize|
+|example<| |small| decode2.py |end_small| |>|
+
+.. sourcecode:: python
+
+    def Message(name, fields):
+        class M(object):
+            def read(self, buf, name):
+                f = getattr(self, name)
+                return struct.unpack_from(f.fmt, buf, f.offset)[0]            
+    
+        for fname, f in fields.iteritems():
+            setattr(M, fname, f)
+    
+        M.__name__ = name
+        return M()
+    
+    Point = Message('Point', {
+        'x': Field('l', 0),
+        'y': Field('l', 4),
+        'color': Field('i', 8)
+        })
+    
+     ...
+     x = Point.read(p, 'x')
+     ...
+
+|end_example|
+|end_scriptsize|
+
+Example: faster API
+----------------------------
+
+|scriptsize|
+|example<| |small| decode2.py trace (3) |end_small| |>|
+
+.. sourcecode:: python
+
+    debug_merge_point(1, 1, '<code object read> #36 CALL_METHOD')
+    +670: i104 = strlen(p101)
+    +673: i105 = int_lt(i104, 4)
+    guard_false(i105, descr=<Guard0xb3afac10>)
+    +682: i106 = strgetitem(p101, 0)
+    +686: i107 = strgetitem(p101, 1)
+    +696: i108 = int_lshift(i107, 8)
+    +699: i109 = int_or(i106, i108)
+    +701: i110 = strgetitem(p101, 2)
+    +717: i111 = int_lshift(i110, 16)
+    +720: i112 = int_or(i109, i111)
+    +722: i113 = strgetitem(p101, 3)
+    +726: i114 = int_ge(i113, 128)
+    guard_false(i114, descr=<Guard0xb3afabe0>)
+    +738: i115 = int_lshift(i113, 24)
+    +741: i116 = int_or(i112, i115)
+
+|end_example|
+|end_scriptsize|
+
+What happened?
+---------------
+
+- dict lookups inside classes are specialized
+
+- decode1.py
+
+  * ``fields`` is "normal data" and expected to change
+
+  * one JIT code for **all** possible messages
+
+- decode2.py
+
+  * ``fields`` is expected to be constant
+
+  * one JIT code for **each** message
+
+- Behaviour is the same, different performance
+
+
+Example: even better API :)
+-----------------------------
+
+|scriptsize|
+|example<| |small| decode3.py |end_small| |>|
+
+.. sourcecode:: python
+
+    class Field(object):
+        def __init__(self, fmt, offset):
+            self.fmt = fmt
+            self.offset = offset
+    
+        def __get__(self, obj, cls):
+            return struct.unpack_from(self.fmt, obj._buf, self.offset)[0]
+    
+    class Point(object):
+        def __init__(self, buf):
+            self._buf = buf
+    
+        x = Field('l', 0)
+        y = Field('l', 4)
+        color = Field('h', 8)
+    
+    def main():
+        res = 0
+        for p in PLIST:
+            p = Point(p)
+            res += p.x
+        print res
+
+|end_example|
+|end_scriptsize|
+
 
 
 Contacts, Q&A
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to