On Sunday 27 November 2005 18:24, Tom Albers wrote: | Jesper K. Pedersen wrote: | > I'm all for this change. Faster start up is a good thing. | | I doubt that ;-) | When it results in unresponsive gui when people choose to do a | kipi-action, because it has to load the kipi-plugin, I would rather | think it is a very bad thing. I rather have a small delay in startup | then delays when using the program. Well that depends on the pattern of usage, doesn't it? If people use plugins in almost all invocation of the application, then I agree that delayed loading isn't a good thing, on the other hand if they are seldom used, then I'm all for delaying loading them. | > Having said that, I don't have any time to put into this (just see | | how long it | | > took to answer this email ;) | | That is the problem with the digikam-team at the moment the same. We do | not have time to change the kipi-interface, so that would form a problem | for us. | | > If you are going for this, I think it would be really good if the two | > kipi versions could co exists. Also it would be really nice to have a | > check up on KIPI over all if we break BIC. See the libkipi/TODO for some | > suggestions. | | Yes, I agree. Co existant would give us the flexibility to change | digiKam in a later stage. I would like to point out that it should be | done after a final release and that there will be extensive valgrind | testing to make sure it behaves correctly. | | Tom | | > Cheers | > Jesper. | > | > On Monday 24 October 2005 16:18, Aurelien Gateau wrote: | > | Here is my proposal. | > | | > | ---------- Message transmis ---------- | > | | > | Subject: [Kde-imaging] On-demand-loading of KIPI plugins | > | Date: Mercredi 12 Octobre 2005 23:51 | > | From: Aurelien Gateau | > | To: kde-imaging@kde.org | > | | > | Hello, | > | | > | We (Gwenview developers) have been receiving a few complaints lately | > | about Gwenview memory usage and startup speed. | > | | > | One way to improve on this would be to implement on-demand-loading of | > | KIPI plugins. That is: instead of dlopening all plugins on application | > | startup, we would dlopen them only when a plugin action is triggered | > | from the menu. I decided to have a look at what it would take to | > | implement this and came up with a simple proof-of-concept | > | implementation, which you will find attached to this message. | > | | > | kipi2-libkipi.diff contains all changes to libkipi. | > | kipi2-kipi-plugins.diff contains the changes to the kipi-plugins I | > | ported to (helloworld, calendar, printwizard and jpeglossless). | > | | > | I hopefully didn't break source compatibility (I did break binary | > | compatibility), so if you fill adventurous you can try to rebuild your | > | app with this new lib (I must confess I only tried it with Gwenview) | > | | > | | > | Some numbers | > | ------------ | > | | > | Since measuring memory usage is a difficult art, only mastered by a few | > | wise people :-) I restricted myself to measuring improvements on | > | startup time. I hope you will all agree that not dlopening files leads | > | to less memory usage (I would be interested to get some reliable | > | numbers on memory usage, nevertheless). | > | | > | My machine is a Duron 1200, with 768Mb of RAM and a decent UltraDMA IDE | > | disk. Here is how I ran my tests: | > | * Uninstalled my packaged version of kipi-plugins | > | | > | * Patched the plugin-loading code of Gwenview like this: | > | + QTime chrono; | > | + chrono.start(); | > | // Sets up the plugin interface, and load the plugins | > | KIPIInterface* interface = new KIPIInterface(this, mFileViewStack); | > | mPluginLoader = new KIPI::PluginLoader(QStringList(), interface ); | > | connect( mPluginLoader, SIGNAL( replug() ), this, SLOT( slotReplug() ) | > | ); mPluginLoader->loadPlugins(); | > | + kdDebug() << "Load plugins: " << chrono.elapsed() << endl; | > | | > | * Rebuild the current libkipi,kipi-plugins and installed them as well | > | as Gwenview to $HOME/opt/debug (my usual debug install dir). | > | | > | * Ran "export KDEDIRS=$HOME/opt/debug:/usr", then "kbuildsycoca" | > | | > | * Started Gwenview three times, results (in milliseconds) are: | > | 1175 1042 1030 (Mean: 1082.3) | > | | > | | > | Second set of tests, using only the KIPI2 ported plugins: | > | * cd'ed into share/services/ and rm'ed the .desktop files for the | > | plugins which was not ported to KIPI2. | > | | > | * run kbuildsycoca | > | | > | * Started Gwenview three times, results are: | > | 264 238 308 (Mean: 270) | > | | > | | > | Third set of tests, this time using KIPI2: | > | * Build KIPI2 version of libkipi,kipi-plugins,gwenview and installed | > | them to $HOME/opt/kipi2 | > | | > | * Ran "export KDEDIRS=$HOME/opt/kipi2", then "kbuildsycoca" | > | | > | * Started Gwenview three times, results are: | > | 74 56 55 (Mean: 61.6) | > | | > | | > | As you can see, it's more than 4 times faster. | > | | > | | > | How does it work? | > | ----------------- | > | | > | KIPI::Plugin acts as a proxy for the real plugin, which inherits from | > | KIPI::RealPlugin. KIPI::Plugin objects are instanciated on application | > | startup and create KActions based on the action definitions of the | > | plugin desktop files. | > | | > | The desktop file looks like this: | > | | > | [Desktop] | > | ... | > | Actions=action1;action2 | > | | > | [Desktop Action action1] | > | Name=Action1 | > | Name[fr]=Action1 FR | > | Icon=back | > | Category=1 | > | | > | [Desktop Action action2] | > | Name=Action2 | > | Name[fr]=Action2 FR | > | Icon=forward | > | Category=2 | > | | > | | > | All actions of a plugin are connected to the same KIPI::Plugin slot | > | (slotActionActivated() ) which will first load and init the plugin if | > | necessary, then execute the corresponding plugin slot. To execute the | > | right slot It uses a little trick like this: | > | | > | ------- | > | // Get the action name: this is the name of the plugin slot to call | > | const QObject* obj=sender(); | > | Q_ASSERT(obj); | > | QCString name=obj->name(); | > | | > | // Create the slot based on the action name, then call it | > | QSignal signaler; | > | signaler.connect(d->m_realPlugin, "1" + name + "()"); | > | signaler.activate(); | > | ------- | > | | > | On the plugin side there are no KActions, only slots. In my example, | > | there are two slots named action1() and action2(). | > | | > | | > | Limitations | > | ----------- | > | | > | There is no support for enabling or disabling actions. This can be | > | easily implemented through another key in the action group which would | > | specify what is necessary for the plugin. Some plugins want to have | > | some images selected, others will work without any selection, letting | > | the user choose between the application image collections. | > | | > | There is also no support for submenus. Again, this could be implemented | > | using keys in the action group, but from a usability point of view I'm | > | not sure it's a good idea: deep nested menus are not very handy to use. | > | | > | The current code is just a proof of concept, and I tried to avoid | > | breaking source compatibility so that it's easier to test, but if we go | > | for this a few things should probably be written in a different way | > | (for example the PluginInfo and Plugin class should be merged). | > | | > | | > | What do you think about this? | > | | > | Regards, | > | Aurélien | > | | > | ------------------------------------------------------- -- Jesper K. Pedersen          |  Klarälvdalens Datakonsult Senior Software Engineer    |  www.klaralvdalens-datakonsult.se Prinsensgade 4a st. | 9800 Hjørring              |  Platform-independent Denmark                     |  software solutions _______________________________________________ Kde-imaging mailing list Kde-imaging@kde.org https://mail.kde.org/mailman/listinfo/kde-imaging