Page MenuHomePhabricator

Improve performance of Title::isMainPage
Closed, ResolvedPublic

Description

Title::isMainPage is run once for every link on a page to determine what the localURL should be (and apparently 3 times for each file on a page, but that's a story for later). It's also used pretty frequently by hooks like onGetLocalURLInternal, and a moderately sized page can easily have 1000-2000 calls to it.

Despite this, it's a surprisingly expensive call, because it calls Title::newMainPage() every time. This doesn't technically create a new Title object every time due to the newFromText cache, but the expensive part is where it gets the "mainpage" message from the MessageCache. It's not outrageously expensive, but 20-30 μs for each call adds up if it's called 1000-2000 times per page.

Since Title::newMainPage() is a static method, can we just cache the result when it's called from Title::isMainPage? Here's some example code that I'm sure could be improved (I'm fairly new to MediaWiki perf stuff):

Change from

public function isMainPage() {
        return $this->equals( self::newMainPage() );
}

to

public function isMainPage() {
        if (isset(self::$mainPage)) {
                return $this->equals( self::$mainPage );
        }
        self::$mainPage = self::newMainPage();
        return $this->equals( self::$mainPage );
}

I can't speak for the general case, but for runescape.wiki this little change reduces the average parse time of pages by about 8%.

Event Timeline

A little more investigation suggests that this is mainly an issue for wikis with $wgMainPageIsDomainRoot = true, which is not the case for WMF.

Instance caching newMainPage() seems reasonable to me. You might need to guard it on !defined( 'MW_PHPUNIT_TEST' ) but that's a pretty common pattern.

Change 911061 had a related patch set uploaded (by TehKittyCat; author: TehKittyCat):

[mediawiki/core@master] Add title cache for Title::newMainPage()

https://gerrit.wikimedia.org/r/911061

Change 911061 merged by jenkins-bot:

[mediawiki/core@master] Add title cache for Title::newMainPage()

https://gerrit.wikimedia.org/r/911061

matmarex subscribed.