We have moved to Github. Please open tickets there.

#4251 closed Enhancement (wontfix)

Optimization for elgg_get_plugin_from_id

Reported by: srokap Owned by:
Priority: normal Milestone: Elgg 1.8.7
Component: Core Version: 1.8.1b1
Severity: minor Keywords:
Cc: brett@… Difficulty:

Description (last modified by ewinslow)

I've noticed that when using multiple plugin settings, good piece of a second is taken by multiple elgg_get_plugin_from_id calls. It seems it's written not efficient to say the least.

We've made some optimization for this function, we fetch all of the plugins data by single call and instantiate objects in lazy manner. Such approach saved us about 20-30 DB calls, and sum of the runtime dropped from 200-300ms to around 10ms.

Patch in attachment.

Attachments (1)

plugins_queries_optimization.patch (1.3 KB) - added by srokap 17 months ago.
patch for file engine/lib/plugins.php

Download all attachments as: .zip

Change History (8)

Changed 17 months ago by srokap

patch for file engine/lib/plugins.php

comment:1 Changed 17 months ago by srokap

P.S. Original code version should be 1.8.2 but I can't find it in the list, is it normal or I'm missing something?

comment:2 Changed 13 months ago by ewinslow

  • Description modified (diff)
  • Milestone changed from Needs Review to Near Term Future Release

Can you submit this as a pull request on github? This definitely sounds like a nice optimization.

comment:3 Changed 13 months ago by srokap

I've opened pull request. It seems that my fork went quite messy. Final difference changes only one file. https://github.com/Elgg/Elgg/pull/209

comment:4 Changed 11 months ago by cash

  • Milestone changed from Near Term Future Release to Elgg 1.8.7

Too much noise in the pull request. Here is the relevant code that I could find:

function elgg_get_plugin_from_id($plugin_id) {
	$plugin_id = sanitize_string($plugin_id);
	$db_prefix = get_config('dbprefix');

	static $plugins;
	static $pluginsRaw;
	
	if(!is_array($plugins)) {
		$options = array(
			'type' => 'object',
			'subtype' => 'plugin',
			'joins' => array("JOIN {$db_prefix}objects_entity oe on oe.guid = e.guid"),
			'callback' => '',//fetch raw data
			'selects' => array('oe.title'),
			'limit' => 0,
		);
		$pluginsRet = elgg_get_entities($options);
		$plugins = array();
		$pluginsRaw = array();
		foreach($pluginsRet as $row) {
			$pluginsRaw[$row->title] = $row;
		}
	}
	
	if(isset($plugins[$plugin_id])) {
		return $plugins[$plugin_id];
	}
	else if(isset($pluginsRaw[$plugin_id])) {//make lazy conversion
		$plugins[$plugin_id] = entity_row_to_elggstar($pluginsRaw[$plugin_id]);
		return $plugins[$plugin_id];
	}

	return false;
}

I'm assigning this to 1.8.7 so that we look at it and re-evaluate due to changing how we load plugins.

comment:5 Changed 11 months ago by srokap

It seems I've messed up some of old pull requests after rebasing - it should be single commit there. Changes were only to this function. It's obviously better to have single mechanism than separate.

comment:6 Changed 11 months ago by cash

Generally, we are going to load a plugin from id when it is already an active plugin. We have already loaded active plugins. If we stored the plugin objects in a cache, we could hit the cache before trying to hit the database. It's likely it would never go to database. This would be better than having a static cache within this single function.

comment:7 Changed 11 months ago by srokap

  • Resolution set to wontfix
  • Status changed from new to closed

Exactly, when having plugins in entity cache only thing left to do is to store and use mapping between plugin_id and GUID somehow. This ticket becomes obsolete if that's taken care of and such solution is much better than optimizing single function.

See: #4313 and #4543

Note: See TracTickets for help on using tickets.