I think you may be best off with ToscaWidgets and Mako for this particular use case.
Mako has a lot more caching options, and the large number of widgets you're using highlights some of the performance issues that you may find in Kid when rendering large pages. We recently had to replace a kid template that was taking 9 seconds to render (it was one HUGE table) with Mako, and our render time droped down to 0.04 seconds. And it really didn't take that long either. If you have lots of widgets, and you can rewrite the widget templates in Mako (which requires ToscaWidgets) that will help a lot. TW should be useable in current versions of turbogears, but it badly needs some more documentation so you should expect to look at the source, or ask questions on the mailing list. --Mark On 8/14/07, Brian Cole <[EMAIL PROTECTED]> wrote: > I have a fairly static page containing many widgets (100+). I've done > all I can to cache widget instantiation so that no widgets are > actually instantiated (unless a particular cached widget has become > stale) during the page call. This shaved about 3 seconds off of 9 > second page load. > > The expose(template="page") decorator around my method is still taking > a long time. The perpetrator appears to be Kid. Here is the profile > output showing it: > Tue Aug 14 18:10:02 2007 ./profile/cp_0026.prof > > 7030416 function calls (3574371 primitive calls) in 29.440 CPU > seconds > > Ordered by: cumulative time > > ncalls tottime percall cumtime percall filename:lineno(function) > 1 0.000 0.000 29.440 29.440 profile:0(<bound method > Request._run of <cherrypy._cphttptools.Request object at 0x2c65990>>) > 1 0.000 0.000 29.440 29.440 _cphttptools.py:82(_run) > 1 0.000 0.000 29.430 29.430 > controllers.py:376(_execute_func) > 1 0.000 0.000 29.430 29.430 controllers.py:333(expose) > 1 0.000 0.000 29.430 29.430 <string>:4(_expose) > 1 0.000 0.000 29.430 29.430 <string>:2(admin) > 1 0.000 0.000 29.430 29.430 controllers.py:356(<lambda>) > 1 0.000 0.000 29.430 29.430 <string>:4(run_with_transaction) > 1 0.000 0.000 29.430 29.430 _cphttptools.py:241(main) > 1 0.000 0.000 29.430 29.430 database.py:303(so_rwt) > 1 0.000 0.000 29.350 29.350 > controllers.py:30(_process_output) > 9079/38 0.140 0.000 29.150 0.767 :0(join) > 1 0.000 0.000 29.150 29.150 base.py:99(render) > 1 0.000 0.000 29.150 29.150 serialization.py:104(serialize) > 1 0.000 0.000 29.150 29.150 kidsupport.py:150(render) > 1 0.000 0.000 29.150 29.150 kid/__init__.py:276(serialize) > 44138 0.810 0.000 29.080 0.001 serialization.py:564(generate) > 33374 0.280 0.000 27.180 0.001 > serialization.py:140(format_stream) > 279479/28078 2.740 0.000 26.460 0.001 parser.py:209(_coalesce) > 28078 0.150 0.000 26.170 0.001 > serialization.py:468(inject_meta_tags) > 840227/28075 3.590 0.000 26.020 0.001 parser.py:174(_track) > 251486/28075 1.440 0.000 25.880 0.001 filter.py:25(apply_matches) > 1806/12 1.120 0.001 23.360 1.947 parser.py:96(expand) > 28015 0.100 0.000 20.690 0.001 admin.py:26(_pull) > 1802/9 0.040 0.000 19.290 2.143 kidsupport.py:197(transform) > 1063/1 0.000 0.000 19.290 19.290 base.py:356(display) > 86/1 0.000 0.000 19.290 19.290 meta.py:102(lockwidget) > 1802/9 0.080 0.000 19.290 2.143 base.py:233(display) > 176312/27986 1.280 0.000 17.930 0.001 <string>:24(_pull) > 85/17 0.010 0.000 14.040 0.826 > togglesection.py:61(update_params) > 2152800/226209 7.230 0.000 7.930 0.000 parser.py:156(_pull) > 11543/153 0.120 0.000 5.110 0.033 forms.py:49(_update_path) > 1054/153 0.000 0.000 5.100 0.033 forms.py:235(display) > 28032 0.130 0.000 1.610 0.000 sitetemplate.py:66(_match_func) > 28032 0.100 0.000 1.380 0.000 master.py:88(_match_func) > 1807 0.250 0.000 1.330 0.001 template_util.py:38(get_locals) > 969 0.010 0.000 1.040 0.001 forms.py:449(update_params) > 488436 1.000 0.000 1.000 0.000 :0(append) > 1803 0.060 0.000 0.810 0.000 base.py:269(stdvars) > 2771 0.070 0.000 0.790 0.000 forms.py:168(_get_name_path) > 1807 0.420 0.000 0.790 0.000 inspect.py:166(getmembers) > 261819/219863 0.520 0.000 0.760 0.000 :0(getattr) > 74693 0.470 0.000 0.720 0.000 element.py:24(__init__) > 1054 0.020 0.000 0.720 0.001 forms.py:250(update_params) > 64044 0.360 0.000 0.630 0.000 element.py:60(append) > 128732 0.400 0.000 0.620 0.000 parser.py:196(to_unicode) > 363520 0.560 0.000 0.560 0.000 :0(isinstance) > 1803 0.010 0.000 0.550 0.000 utils.py:45(get_locale) > 11543 0.090 0.000 0.540 0.000 forms.py:25(append_to_path) > 175503 0.480 0.000 0.480 0.000 :0(pop) > 3062 0.010 0.000 0.470 0.000 > template_util.py:279(make_updated_attrib) > 54906 0.300 0.000 0.470 0.000 > cherrypy/__init__.py:41(__getattr__) > 3885 0.060 0.000 0.450 0.000 > template_util.py:137(make_attrib) > 1803 0.020 0.000 0.450 0.000 utils.py:54(_get_locale) > 12808/6986 0.170 0.000 0.390 0.000 > template_util.py:156(generate_attrib) > 5983 0.050 0.000 0.350 0.000 config.py:210(get) > 82369 0.230 0.000 0.330 0.000 :0(hasattr) > 6001 0.190 0.000 0.300 0.000 config.py:107(get) > 134184 0.290 0.000 0.290 0.000 :0(startswith) > > > The following works for caching the entire page contents but what I > really need to do is cache only portions of the page to allow for > parts to change quickly. > > @expose(template="page") > def _page(self, **kw): > val = self.alterSomething(kw) > return dict(wdgt=self.wdgt, value=val) > > cache = None > @expose() > def page(self, **kw): > if self.cache is None or self.requiresChange(kw): > self.cache = self._page(**kw) > return self.cache > > Caching individual segments of the page will require a lot more > complexity. Is there a way to make Kid go faster? I can't use psyco > because I'm running on an x86_64 machine. I even tried to hack > cElementTree back into Kid (it was taken out for some reason: > http://kid-templating.org/notes.html#celementtree-support) > > Or have I reached the limits of TurboGears and this is why there's > support for other templating engines? And I just really got to like > the TG widget system... > > Thanks, > Brian > > > > -- Mark Ramm-Christensen email: mark at compoundthinking dot com blog: www.compoundthinking.com/blog --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "TurboGears" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/turbogears?hl=en -~----------~----~----~----~------~----~------~--~---

