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

-- 



Reply via email to