On Fri, Apr 26, 2013 at 8:59 PM, Michael Bayer <mike...@zzzcomputing.com> wrote: >>>> All attributes have to be expire-able and act as proxies for a database connection so I'm not really sure where to go with that. I'm not too thrilled about proposals to build in various "alternate performance" behaviors as the library starts to try to act in many different ways that the vast majority of users aren't even aware of, it increases complexity internally, produces vast amounts of new use cases to test and maintain, etc. I'm always willing to look at patches that are all winning, of course, so if you have some way to speed things up without breaking usage contracts and without major new complexity/brittleness I'd love to look at a pull request. >>> >>> I know, it's just a probe to see what kind of a speedup could be >>> obtained by not having that getter's interference. You know... simply >>> implementing InstrumentedAttribute in C could do the trick... >> >> >> In fact... I'm gonna try that... > > feel free! though you might be surprised, a C function that just calls out to all the same Python operations anyway is often only negligibly faster, not enough to make the extra complexity worth it.
Ok, I got around to profiling this. The C extension saves 20s from 800s, as noted before, most of those 800s are SA-unrelated application logic, and the app has been greatly optimized to avoid attribute access, so average speedup would most likely be far more. As expected, the getter disappears from profiles (it's seen as the calling function's time now). I've got a function that makes some unavoidable access to instrumented attributes. It's get_params, it's called around 7M times, so while small, the overhead does add up. I made sure expiration works btw. Without the C extension: ncalls tottime percall cumtime percall filename:lineno(function) 20811734 27.829 0.000 27.855 0.000 attributes.py:171(__get__) 7631984 13.532 0.000 31.851 0.000 ruby.py:86(get_param) With the C extension: ncalls tottime percall cumtime percall filename:lineno(function) 7631984 19.514 0.000 21.051 0.000 ruby.py:86(get_param) Notice how the C extension saves a total of 10s (cumtime, sum of internal and external time). There's no DB access when hitting those arguments, as everything has been eagerly loaded. It's all function call overhead. Assuming an application makes heavy use of attributes, as get_param does (expectable of straightforward code I'd think), that's a 30% speedup of CPU-bound code. As soon as I get GC right I'll post the patch. -- You received this message because you are subscribed to the Google Groups "sqlalchemy" group. To unsubscribe from this group and stop receiving emails from it, send an email to sqlalchemy+unsubscr...@googlegroups.com. To post to this group, send email to sqlalchemy@googlegroups.com. Visit this group at http://groups.google.com/group/sqlalchemy?hl=en. For more options, visit https://groups.google.com/groups/opt_out.