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