From dfd481e113f2cf5aaa305362e0131c4ed998290a Mon Sep 17 00:00:00 2001 From: Tim Starling Date: Thu, 19 Dec 2013 10:44:54 +1100 Subject: [PATCH] Maintenance script for benchmarking parse operations Including a feature allowing templates from some other time to be used, which allows comparative benchmarking before and after the migration of a template to Lua. Change-Id: I3bf3366a5ff589421f6c52e9186e0cea05e6cff3 --- maintenance/benchmarks/benchmarkParse.php | 119 ++++++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 maintenance/benchmarks/benchmarkParse.php diff --git a/maintenance/benchmarks/benchmarkParse.php b/maintenance/benchmarks/benchmarkParse.php new file mode 100644 index 0000000000..79af9111eb --- /dev/null +++ b/maintenance/benchmarks/benchmarkParse.php @@ -0,0 +1,119 @@ +addDescription( 'Benchmark parse operation' ); + $this->addArg( 'title', 'The name of the page to parse' ); + $this->addOption( 'cold', 'Don\'t repeat the parse operation to warm the cache' ); + $this->addOption( 'page-time', + 'Use the version of the page which was current at the given time', + false, true ); + $this->addOption( 'tpl-time', + 'Use templates which were current at the given time (except that moves and deletes are not handled properly)', + false, true ); + } + + function execute() { + global $wgParser; + + if ( $this->hasOption( 'tpl-time' ) ) { + $this->templateTimestamp = wfTimestamp( TS_MW, strtotime( $this->getOption( 'tpl-time' ) ) ); + Hooks::register( 'BeforeParserFetchTemplateAndtitle', array( $this, 'onFetchTemplate' ) ); + } + $title = Title::newFromText( $this->getArg() ); + if ( !$title ) { + $this->error( "Invalid title" ); + exit( 1 ); + } + if ( $this->hasOption( 'page-time' ) ) { + $pageTimestamp = wfTimestamp( TS_MW, strtotime( $this->getOption( 'page-time' ) ) ); + $id = $this->getRevIdForTime( $title, $pageTimestamp ); + if ( !$id ) { + $this->error( "The page did not exist at that time" ); + exit( 1 ); + } + + $revision = Revision::newFromId( $id ); + } else { + $revision = Revision::newFromTitle( $title ); + } + if ( !$revision ) { + $this->error( "Unable to load revision, incorrect title?" ); + exit( 1 ); + } + if ( !$this->hasOption( 'cold' ) ) { + $this->runParser( $revision ); + } + $startUsage = getrusage(); + $startTime = microtime( true ); + $this->runParser( $revision ); + $endUsage = getrusage(); + $endTime = microtime( true ); + + printf( "CPU time = %.3f s, wall clock time = %.3f s\n", + $endUsage['ru_utime.tv_sec'] + $endUsage['ru_utime.tv_usec'] * 1e-6 + - $startUsage['ru_utime.tv_sec'] - $startUsage['ru_utime.tv_usec'] * 1e-6, + $endTime - $startTime ); + } + + /** + * @param Title $title + * @param string $timestamp + * @return bool|mixed + */ + function getRevIdForTime( $title, $timestamp ) { + $dbr = wfGetDB( DB_SLAVE ); + $id = $dbr->selectField( + array( 'revision', 'page' ), + 'rev_id', + array( + 'page_namespace' => $title->getNamespace(), + 'page_title' => $title->getDBkey(), + 'rev_page=page_id', + 'rev_timestamp <= ' . $dbr->addQuotes( $timestamp ) + ), + __METHOD__, + array( 'ORDER BY' => 'rev_timestamp DESC', 'LIMIT' => 1 ) ); + + return $id; + } + + /** + * @param Revision $revision + */ + function runParser( $revision ) { + $content = $revision->getContent(); + $content->getParserOutput( $revision->getTitle(), $revision->getId() ); + } + + /** + * @param Parser $parser + * @param Title $title + * @param $skip + * @param $id + * @return bool + */ + function onFetchTemplate( $parser, $title, &$skip, &$id ) { + $pdbk = $title->getPrefixedDBkey(); + if ( !isset( $this->idCache[$pdbk] ) ) { + $proposedId = $this->getRevIdForTime( $title, $this->templateTimestamp ); + $this->idCache[$pdbk] = $proposedId; + } + if ( $this->idCache[$pdbk] !== false ) { + $id = $this->idCache[$pdbk]; + } + + return true; + } +} + +$maintClass = 'BenchmarkParse'; +require RUN_MAINTENANCE_IF_MAIN; -- 2.20.1