Uploaded image for project: 'Moodle'
  1. Moodle
  2. MDL-52945

Scalability / performance issue with get_used_module_names()

    XMLWordPrintable

    Details

    • Type: Improvement
    • Status: Closed
    • Priority: Minor
    • Resolution: Fixed
    • Affects Version/s: 2.9.4, 3.0.2
    • Fix Version/s: 3.1
    • Component/s: Performance
    • Labels:
    • Testing Instructions:
      Hide

      1. Create a course with a large number of modules (1,000)
      2. Load the course view page and see the page load time.
      3. Revert to master prior to this change being integrated.
      4. Load the course view page and confirm it is higher.

      Show
      1. Create a course with a large number of modules (1,000) 2. Load the course view page and see the page load time. 3. Revert to master prior to this change being integrated. 4. Load the course view page and confirm it is higher.
    • Affected Branches:
      MOODLE_29_STABLE, MOODLE_30_STABLE
    • Fixed Branches:
      MOODLE_31_STABLE
    • Pull Master Branch:

      Description

      For the courses with many (>1k) course modules, there is a scalability issue with get_used_module_names() function.

      When this loop:

              foreach ($this->get_cms() as $cmid => $mod) {
                  if (isset($modnames[$mod->modname]) && $mod->uservisible) {
                      $modnamesused[$mod->modname] = $modnames[$mod->modname];
                  }
              }
      

      iterates over many course modules, it takes significant time for the course view page load. The profiling data from the real-life course (the course has 3.5k labels - but this is actually working just fine - except for this call - because only one section is displayed at the time):

      Function Name	Calls	Calls%	Incl. Wall Time(microsec)	IWall%	Excl. Wall Time(microsec)	EWall%	Incl. CPU(microsecs)	ICpu%	Excl. CPU(microsec)	ECPU%	Incl.MemUse(bytes)	IMemUse%	Excl.MemUse(bytes)	EMemUs%	Incl.PeakMemUse(bytes)	IPeakMemUse%	Excl.PeakMemUse(bytes)	EPeakMemUse%
      course_modinfo::get_used_module_names 	1 	0.0% 	104,476 	8.0% 	7,070 	0.5% 	104,358 	8.5% 	3,822 	0.3% 	758,992 	3.2% 	98,736 	0.4% 	0 	0.0% 	0 	0.0%
      course_modinfo::get_used_module_names 	1 	0.0% 	106,545 	8.4% 	7,110 	0.6% 	107,931 	9.1% 	7,359 	0.6% 	758,624 	3.2% 	98,784 	0.4% 	0 	0.0% 	0 	0.0%
      

      Very simple fix that does not change any logic is:

              foreach ($this->get_cms() as $cmid => $mod) {
                  if(isset($modnamesused[$mod->modname])) {
                      continue;
                  }
                  if (isset($modnames[$mod->modname]) && $mod->uservisible) {
                      $modnamesused[$mod->modname] = $modnames[$mod->modname];
                  }
              }
      

      The profiling run after the fix:

      Function Name	Calls	Calls%	Incl. Wall Time(microsec)	IWall%	Excl. Wall Time(microsec)	EWall%	Incl. CPU(microsecs)	ICpu%	Excl. CPU(microsec)	ECPU%	Incl.MemUse(bytes)	IMemUse%	Excl.MemUse(bytes)	EMemUs%	Incl.PeakMemUse(bytes)	IPeakMemUse%	Excl.PeakMemUse(bytes)	EPeakMemUse%
      course_modinfo::get_used_module_names 	1 	0.0% 	2,285 	0.2% 	2,089 	0.2% 	1,864 	0.2% 	279 	0.0% 	5,424 	0.0% 	2,256 	0.0% 	0 	0.0% 	0 	0.0%
      course_modinfo::get_used_module_names 	1 	0.0% 	2,180 	0.2% 	2,016 	0.2% 	2,045 	0.2% 	844 	0.1% 	5,472 	0.0% 	2,272 	0.0% 	0 	0.0% 	0 	0.0%
      

        Attachments

          Activity

            People

            • Votes:
              2 Vote for this issue
              Watchers:
              8 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:
                Fix Release Date:
                23/May/16