MediaWiki REL1_34
benchmarkParse.php
Go to the documentation of this file.
1<?php
25require __DIR__ . '/../Maintenance.php';
26
28
37 private $templateTimestamp = null;
38
39 private $clearLinkCache = false;
40
44 private $linkCache;
45
47 private $idCache = [];
48
49 function __construct() {
50 parent::__construct();
51 $this->addDescription( 'Benchmark parse operation' );
52 $this->addArg( 'title', 'The name of the page to parse' );
53 $this->addOption( 'warmup', 'Repeat the parse operation this number of times to warm the cache',
54 false, true );
55 $this->addOption( 'loops', 'Number of times to repeat parse operation post-warmup',
56 false, true );
57 $this->addOption( 'page-time',
58 'Use the version of the page which was current at the given time',
59 false, true );
60 $this->addOption( 'tpl-time',
61 'Use templates which were current at the given time (except that moves and ' .
62 'deletes are not handled properly)',
63 false, true );
64 $this->addOption( 'reset-linkcache', 'Reset the LinkCache after every parse.',
65 false, false );
66 }
67
68 function execute() {
69 if ( $this->hasOption( 'tpl-time' ) ) {
70 $this->templateTimestamp = wfTimestamp( TS_MW, strtotime( $this->getOption( 'tpl-time' ) ) );
71 Hooks::register( 'BeforeParserFetchTemplateAndtitle', [ $this, 'onFetchTemplate' ] );
72 }
73
74 $this->clearLinkCache = $this->hasOption( 'reset-linkcache' );
75 // Set as a member variable to avoid function calls when we're timing the parse
76 $this->linkCache = MediaWikiServices::getInstance()->getLinkCache();
77
78 $title = Title::newFromText( $this->getArg( 0 ) );
79 if ( !$title ) {
80 $this->error( "Invalid title" );
81 exit( 1 );
82 }
83
84 if ( $this->hasOption( 'page-time' ) ) {
85 $pageTimestamp = wfTimestamp( TS_MW, strtotime( $this->getOption( 'page-time' ) ) );
86 $id = $this->getRevIdForTime( $title, $pageTimestamp );
87 if ( !$id ) {
88 $this->error( "The page did not exist at that time" );
89 exit( 1 );
90 }
91
92 $revision = Revision::newFromId( $id );
93 } else {
94 $revision = Revision::newFromTitle( $title );
95 }
96
97 if ( !$revision ) {
98 $this->error( "Unable to load revision, incorrect title?" );
99 exit( 1 );
100 }
101
102 $warmup = $this->getOption( 'warmup', 1 );
103 for ( $i = 0; $i < $warmup; $i++ ) {
104 $this->runParser( $revision );
105 }
106
107 $loops = $this->getOption( 'loops', 1 );
108 if ( $loops < 1 ) {
109 $this->fatalError( 'Invalid number of loops specified' );
110 }
111 $startUsage = getrusage();
112 $startTime = microtime( true );
113 for ( $i = 0; $i < $loops; $i++ ) {
114 $this->runParser( $revision );
115 }
116 $endUsage = getrusage();
117 $endTime = microtime( true );
118
119 printf( "CPU time = %.3f s, wall clock time = %.3f s\n",
120 // CPU time
121 ( $endUsage['ru_utime.tv_sec'] + $endUsage['ru_utime.tv_usec'] * 1e-6
122 - $startUsage['ru_utime.tv_sec'] - $startUsage['ru_utime.tv_usec'] * 1e-6 ) / $loops,
123 // Wall clock time
124 ( $endTime - $startTime ) / $loops
125 );
126 }
127
135 function getRevIdForTime( Title $title, $timestamp ) {
136 $dbr = $this->getDB( DB_REPLICA );
137
138 $id = $dbr->selectField(
139 [ 'revision', 'page' ],
140 'rev_id',
141 [
142 'page_namespace' => $title->getNamespace(),
143 'page_title' => $title->getDBkey(),
144 'rev_timestamp <= ' . $dbr->addQuotes( $timestamp )
145 ],
146 __METHOD__,
147 [ 'ORDER BY' => 'rev_timestamp DESC', 'LIMIT' => 1 ],
148 [ 'revision' => [ 'JOIN', 'rev_page=page_id' ] ]
149 );
150
151 return $id;
152 }
153
159 function runParser( Revision $revision ) {
160 $content = $revision->getContent();
161 $content->getParserOutput( $revision->getTitle(), $revision->getId() );
162 if ( $this->clearLinkCache ) {
163 $this->linkCache->clear();
164 }
165 }
166
177 function onFetchTemplate( Parser $parser, Title $title, &$skip, &$id ) {
178 $pdbk = $title->getPrefixedDBkey();
179 if ( !isset( $this->idCache[$pdbk] ) ) {
180 $proposedId = $this->getRevIdForTime( $title, $this->templateTimestamp );
181 $this->idCache[$pdbk] = $proposedId;
182 }
183 if ( $this->idCache[$pdbk] !== false ) {
184 $id = $this->idCache[$pdbk];
185 }
186
187 return true;
188 }
189}
190
191$maintClass = BenchmarkParse::class;
getDB()
wfTimestamp( $outputtype=TS_UNIX, $ts=0)
Get a timestamp string in one of various formats.
const RUN_MAINTENANCE_IF_MAIN
$maintClass
Maintenance script to benchmark how long it takes to parse a given title at an optionally specified t...
LinkCache $linkCache
getRevIdForTime(Title $title, $timestamp)
Fetch the ID of the revision of a Title that occurred.
onFetchTemplate(Parser $parser, Title $title, &$skip, &$id)
Hook into the parser's revision ID fetcher.
__construct()
Default constructor.
runParser(Revision $revision)
Parse the text from a given Revision.
execute()
Do the actual work.
array $idCache
Cache that maps a Title DB key to revision ID for the requested timestamp.
string $templateTimestamp
MediaWiki concatenated string timestamp (YYYYMMDDHHMMSS)
Cache for article titles (prefixed DB keys) and ids linked from one source.
Definition LinkCache.php:34
Abstract maintenance class for quickly writing and churning out maintenance scripts with minimal effo...
error( $err, $die=0)
Throw an error to the user.
addArg( $arg, $description, $required=true)
Add some args that are needed.
hasOption( $name)
Checks to see if a particular option exists.
getArg( $argId=0, $default=null)
Get an argument.
addDescription( $text)
Set the description text.
addOption( $name, $description, $required=false, $withArg=false, $shortName=false, $multiOccurrence=false)
Add a parameter to the script.
getOption( $name, $default=null)
Get an option, or return the default.
fatalError( $msg, $exitCode=1)
Output a message and terminate the current script.
MediaWikiServices is the service locator for the application scope of MediaWiki.
PHP Parser - Processes wiki markup (which uses a more user-friendly syntax, such as "[[link]]" for ma...
Definition Parser.php:74
getTitle()
Returns the title of the page associated with this entry.
Definition Revision.php:559
getId()
Get revision ID.
Definition Revision.php:442
getContent( $audience=self::FOR_PUBLIC, User $user=null)
Fetch revision content if it's available to the specified audience.
Definition Revision.php:719
static newFromTitle(LinkTarget $linkTarget, $id=0, $flags=0)
Load either the current, or a specified, revision that's attached to a given link target.
Definition Revision.php:138
static newFromId( $id, $flags=0)
Load a page revision from a given revision ID number.
Definition Revision.php:119
Represents a title within MediaWiki.
Definition Title.php:42
const DB_REPLICA
Definition defines.php:25
$content
Definition router.php:78