Looks like we finally nailed it. Thanks to Jonathan and Omar from
lang.python mailing list.
1) class Storage has been rewritten and accessing request.something is
now 5x-10x faster.
Storage is used everywhere it may have a big effect on some web2py
apps.
2) class Row, class Table and class DAL have been written using the same
principles. (*)
As result of the changes in 2, the time to define a table (20 fields)
dropped from ~2ms to ~1ms (2x)
This is without using lazy tables which are also in trunk.
With lazy tables and not special attributes, the time dropped to ~3e-2ms
(~80x)
The time to retrieve a row value dropped from ~6e-3ms to ~3e-4ms (20x)
This is important because this is what you do when you loop over rows and
print the values in a view.
It would be nice to have some benchmarks for real life applications.
(*) what's the principle? The magic below:
class Storage(dict):
def __init__(self, ...):
self.__dict__ = self
The allows storage of dict-like elements in the same place as attributes
without need to overload getattr and getattr and it is faster. It does not
seem to break any existing APIs.
PLEASE CHECK IT. If nothing breaks this is going into 2.0 next week and it
will be hard to undo it.
Massimo
My benchmark code:
import time
n = 1000
db=DAL(lazy_tables=False)
fields = [Field('name')]+[Field('f%s'%k) for k in range(20)]
db.define_table('t',*fields)
t0 = time.time()
for k in range(n):
db.define_table('t%s'%k,*fields,**dict(migrate=False))
print (time.time()-t0)/n
db.t.insert(name='max')
t0 = time.time()
for k in range(n):
row = db(db.t).select().first()
print (time.time()-t0)/n
t0 = time.time()
for k in range(n):
row.name=row.name # time to retrieve data
print (time.time()-t0)/n
--