partiallydisassembled.net

Ye olde bloggery

2007-08-25 11:57:40

This update fixes many bugs from previous and works in more browsers (i.e., no more JavaScript). Other features: * Amazing WYSIWYG comment and post editor! * rel=nofollow * RSS feed includes body * permalinks Hope you like your monospace :-)

Richard writes:

M M OO N N OO SSS PPP AA CCC EEEE MM MM O O NN N O O S P P A A C E M M M O O N NN O O SS PPP AAAA C EE M M O O N N O O S P A A C E M M OO N N OO SSS P A A CCC EEEE RRR OO CCC K K SSS R R O O C K K S RRR O O C KK SS R R O O C K K S R R OO CCC K K SSS :)

Faster dispatch

2007-08-21 18:42:15

Here's something that's almost certainly useless to everybody; faster dispatch of static methods:: def faststatic(func): class _c(object): __call__ = func return _c Profiled with:: class ns(object): class SlowClass(object): @staticmethod def foo(): return 1 class FastClass(object): @faststatic def foo(): return 1 import sys sys.modules['ns'] = ns() timeit.Timer('x.foo()', 'import ns; x = ns.SlowClass()').repeat() timeit.Timer('x.foo()', 'import ns; x = ns.FastClass()').repeat() Results are:: SlowClass: 0.439791917801 FastClass: 0.390356063843 The speedup is due to avoiding the _get_ descriptor call, which is completely unnecessary for static methods. A similar performance benefit can be gained with instance methods if you're willing to bind the method during instantiation; here done with a metaclass:: def fastinstance(func): class _c(object): _prebind = True @staticmethod def bind(obj): class _d(object): __call__ = lambda *args, **kwargs: func(obj, *args, **kwargs) return _c class fastdispatch(type): def __init__(cls, name, bases, dict): prebound = [n for n, f in dict.items() if hasattr(f, '_prebind')] old_init = dict.get('__init__') def init(self, *args, **kwargs): for name in prebound: getattr(self, name).bind(self) if old_init: old_init(self, *args, **kwargs) setattr(cls, '__init__', init) super(fastdispatch, cls).__init__(name, bases, dict) Profiled with:: class ns(object): class SlowClass(object): def foo(self): return self class FastClass(object): __metaclass__ = fastdispatch @fastinstance def foo(self): return self import sys sys.modules['ns'] = ns() timeit.Timer('x.foo()', 'import ns; x = ns.SlowClass()').repeat() timeit.Timer('x.foo()', 'import ns; x = ns.FastClass()').repeat() Results are:: SlowClass: 0.59463095665 FastClass: 0.383502960205 You pay for the dispatch speedup at instantiation:: timeit.Timer('X()', 'from ns import SlowClass as X').repeat() timeit.Timer('X()', 'from ns import FastClass as X').repeat() SlowClass 0.0308895111084 FastClass 46.911907196 All times are in microseconds, test bed was:: Python 2.5.1 (r251:54863, May 2 2007, 16:56:35) [GCC 4.1.2 (Ubuntu 4.1.2-0ubuntu4)] on linux2 Linux aholkner-desktop 2.6.20-16-generic #2 SMP Thu Jun 7 20:19:32 UTC 2007 i686 GNU/Linux Intel(R) Pentium(R) 4 CPU 3.00GHz

Conserve

2007-08-19 22:55:28

'tis the weekend for releases. Here is Conserve, a PyWeek #5 warmup entry.

André Roberge writes:

I\'m just learning to use pyglet from scratch. I\'m *extremely* impressed by it, and by conserve which I just found today. I have no experience writing games but plan to learn by teaching my kids to write a super-Mario type game (I\'ve started writing a very basic tutorial for them, which I will make public when they give me feedback). Great work!

embryo

2007-08-19 12:16:04

Announcing embryo, a tiny GUI toolkit for checking that other, larger, GUI toolkits are installed. It has a message box! Native to Mac OS X, Windows and Linux (GTK), less than 4kb compressed.

pyglet-1.0alpha2

2007-08-18 18:04:14

...has landed.