Tags:
object_oriented1Add my vote for this tag plugin1Add my vote for this tag plugin_api1Add my vote for this tag create new tag
view all tags

Introducing the OO style plugins

As shown in another topic (look for it), could be very practical to have a common Base plugin and make new plugins to extends from this base plugin. This could remove the need for the TWiki::Func module altogether, or at least put all the code referencing it in one place. Also it can make initiatives like the TWiki::Plugins.CodeContribution easier to do (every common stuff will be in the base plugin, for example).

So, this research has 2 focus:

  • To provide a OO framework for plugins.
  • Keep the performance at least as good as Cairo.

Benchmarking

I created 2 twiki installations : One base instalation to serve as a reference point for the benchmarks, and a OO instalation for the development.

The most representative script of the TWiki operation is the view script. In Cairo, it is basicaly 2 calls:

  • a call to TWiki::initialize
  • a call to TWiki::UI::View

I measured each call using the attached script and fixtures.

Time is the CPU time reported by the Benchmark module. 10 iteration where used. The average time is easily calculated (that's why I choose 10 iterations), so the total time of the 10 runs is shown.

Pages used for testing:

Result

If you want to see the step-by-step process, check PluginOOApiJournal

With both the TWiki:Plugins.TablePlugin and TWiki:Plugins.DefaultPlugin converted to OO style, these are the numbers

Control installation (With only TWiki:Plugins.TablePlugin and TWiki:Plugins.DefaultPlugin active)

Page initialize view Total
Main.PerformanceBlankPage 0.73 1.98 2.71
Main.WebHome 0.75 2.91 3.67
Main.PerformanceTestPage 0.75 2.22 2.97
TWiki.GoodStyle 0.77 2.37 3.14
TWiki.TextFormattingRules 0.82 6.90 7.72
TWiki.DefaultPlugin 0.75 2.59 3.34
TWiki.TablePlugin 0.78 5.57 6.35

OO Installation

Page initialize view Total
Main.PerformanceBlankPage 0.75 2.01 2.76
Main.WebHome 0.76 2.92 3.67
Main.PerformanceTestPage 0.77 2.25 3.02
TWiki.GoodStyle 0.74 2.37 3.11
TWiki.TextFormattingRules 0.90 6.74 7.64
TWiki.DefaultPlugin 0.78 2.53 3.31
TWiki.TablePlugin 0.86 5.52 6.38

The numbers are very close. I can't figure out why there is such a big difference in the initialization code between calls (the variation is more evident seeing the step-by-step process in PluginOOApiJournal)

Additional Findings

  • Relying on the AUTOLOAD to ignore calls to undefined subs, lazyload the preferences into the object hash and other stuff has a severe impact on the performance.
  • With 8 plugins installed, using the DISABLEDPLUGINS preference to disable all but two (TWiki:Plugins.DefaultPlugin and TWiki:Plugins,TablePlugin), the initialization time for plugis was about 0.240 secs per call (2.40 secs for 10 calls), but uninstalling 6 of those plugins (remove or rename the .pm file) gives an initialization time of 0.077 secs per call!. The rendering process for all the plugins is only 22% more than the rendering for two plugins..
  • Turning On the DEBUG flag and having a lot of debug statements during benchmark is BAD smile (see PluginOOApiJournal)
  • Both OO plugins and traditional plugins can coexist without a severe performance penalty.
  • If there are some plugins listed in the preference INSTALLEDPLUGINS, the Plugins::initialize1 will register those plugins twice (thus performing the whole operation up until the question
    if (!$user)
    ). This is not an issue if only 1 or 2 plugins are listed, but it can be a severe penalty if more than 10 are listed.
  • The Plugin::registerPlugin sub does three things: check if the plugin can be called (has a valid topic), retrieve the $user if the $user is unknown (when called from Plugin::initialize1), register the plugin when the $user is known (when called from Plugin::initialize2)
  • In some cases, the OO plugin perform faster than the traditional plugin.

Further Researchs and questions

  • Futher study is needed to test how the performance is impacted by adding another plugin of each kind (00 and traditional)
  • This may sound weird, but Plugins::applyHandlers is being called 7 times before the plugins initialization. Further research is needed.
  • During the rendering process, why is there a need to cicle line by line and then call outsidePREHandler and insidePREHandler for each line as apropiate?

-- RafaelAlvarez - 08 Sep 2004

Content of the attached file

File Description
/data/PerformanceBlankPage.txt
Blank Page (with only a -) used for performance tests
/data/PerformanceTestPage.txt
A page that don't use any plugin used for performance tests
/data/TWikiPerformance.txt
The page with the Journal of this experiments
/data/WebHome.txt
The webhome found in the control installation
/lib/TWiki/Plugins.pm
The modified Plugin.pm
/lib/TWiki/Contrib/Test/Mock/MockCGI.pm
A Mock of the CGI module
/lib/TWiki/Plugins/DefaultPlugin.pm
The OO version of TWiki:Plugins.DefaultPlugin
/lib/TWiki/Plugins/PluginSkel.pm
The base OO plugin. All OO-styled plugins must extends this
/lib/TWiki/Plugins/TablePlugin.pm
The OO version of TWiki:Plugins.TablePlugin
/tools/bench
The shellscript used to collect the results
/tools/*.fix
All the fixtures used
/tool/timeview.pl
The Perl script used to test performance. Uses the Benchmark module

Comments

Interesting work. Very much reflects my own experience when optimising the Plugins discovery mechanism.

I find it very difficult to theorise why there is such sensitivity in the initialisation process. I have benchmark programs that when run 5 times in succession have up to 20% variance in initialisation time, and it's different for each set of 5 runs. I suspect the problem is that the benchmarks run so quickly that the sampling just isn't frequent enough to give a true picture.

The applyHandlers calls before initialisation are coming from getSessionValue, which is in turn called from getPreferencesValue. Using caller I tracked it down to here:

Plugins::initialize1 start
TWiki::Prefs,../lib/TWiki/Prefs.pm,777 INSTALLEDPLUGINS
TWiki::Prefs,../lib/TWiki/Prefs.pm,777 DISABLEDPLUGINS
Plugins::initialize1 end
So it's actually only the first two that are done before handler registration, so I guess neither of them can be session variables. Which seems OK, though to me they are constants that should be in TWiki.cfg, not TWiki variables, especially given the cost of expanding them all the time.

-- CrawfordCurrie - 09 Sep 2004

There should be another mechanism to specify which plugins are disabled (something like a disable/enable button in the plugin page or in some admin panel or something) and to specify the rendering order of the plugins (the sole purpose of INSTALLEDPLUGINS, AFAIK). I notice that in the attached implementation the ordering is not being respected, because I treated INSTALLEDPLUGINS and the discovered plugins as the same thing.

-- RafaelAlvarez - 09 Sep 2004

Topic attachments
I Attachment History Action Size Date Who Comment
Compressed Zip archivezip PluginOOApi.zip r1 manage 28.6 K 2004-09-08 - 19:03 UnknownUser Files needed to see this in action, along the modified Plugins.pm
Edit | Attach | Watch | Print version | History: r4 < r3 < r2 < r1 | Backlinks | Raw View | Raw edit | More topic actions
Topic revision: r4 - 2004-09-09 - RafaelAlvarez
 
  • Learn about TWiki  
  • Download TWiki
This site is powered by the TWiki collaboration platform Powered by Perl Hosted by OICcam.com Ideas, requests, problems regarding TWiki? Send feedback. Ask community in the support forum.
Copyright © 1999-2026 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.