Added a --profiler option to all maintenance scripts.
authorAaron Schulz <aschulz@wikimedia.org>
Thu, 23 May 2013 21:06:00 +0000 (14:06 -0700)
committerAaron Schulz <aschulz@wikimedia.org>
Thu, 23 May 2013 21:20:51 +0000 (14:20 -0700)
* This dumps profiling information in list or trace format as specified.
* Also optimized wfProfile* function like the ProfileSection class, which
  also plays better with Profiler::setInstance().
* Fixed fatals due to wfDebug() calls in Profiler::instance() due to that
  function not yet being loaded. The calls were simply removed.
* Cleaned up file performance test script a bit.

Change-Id: I6b8cd8b30fefc1904eeeeacada7a30a46f62fe2a

includes/profiler/Profiler.php
maintenance/Maintenance.php
maintenance/fileOpPerfTest.php

index 194bafe..7ca4c2d 100644 (file)
  * @param string $functionname name of the function we will profile
  */
 function wfProfileIn( $functionname ) {
-       global $wgProfiler;
-       if ( $wgProfiler instanceof Profiler || isset( $wgProfiler['class'] ) ) {
+       if ( Profiler::$__instance === null ) { // use this directly to reduce overhead
+               Profiler::instance();
+       }
+       if ( Profiler::$__instance && !( Profiler::$__instance instanceof ProfilerStub ) ) {
                Profiler::instance()->profileIn( $functionname );
        }
 }
@@ -42,8 +44,10 @@ function wfProfileIn( $functionname ) {
  * @param string $functionname name of the function we have profiled
  */
 function wfProfileOut( $functionname = 'missing' ) {
-       global $wgProfiler;
-       if ( $wgProfiler instanceof Profiler || isset( $wgProfiler['class'] ) ) {
+       if ( Profiler::$__instance === null ) { // use this directly to reduce overhead
+               Profiler::instance();
+       }
+       if ( Profiler::$__instance && !( Profiler::$__instance instanceof ProfilerStub ) ) {
                Profiler::instance()->profileOut( $functionname );
        }
 }
@@ -115,12 +119,10 @@ class Profiler {
         * @return Profiler
         */
        public static function instance() {
-               if ( is_null( self::$__instance ) ) {
+               if ( self::$__instance === null ) {
                        global $wgProfiler;
                        if ( is_array( $wgProfiler ) ) {
                                if ( !isset( $wgProfiler['class'] ) ) {
-                                       wfDebug( __METHOD__ . " called without \$wgProfiler['class']"
-                                               . " set, falling back to ProfilerStub for safety\n" );
                                        $class = 'ProfilerStub';
                                } else {
                                        $class = $wgProfiler['class'];
@@ -129,8 +131,6 @@ class Profiler {
                        } elseif ( $wgProfiler instanceof Profiler ) {
                                self::$__instance = $wgProfiler; // back-compat
                        } else {
-                               wfDebug( __METHOD__ . ' called with bogus $wgProfiler setting,'
-                                               . " falling back to ProfilerStub for safety\n" );
                                self::$__instance = new ProfilerStub( $wgProfiler );
                        }
                }
index 98b7d47..b4df328 100644 (file)
@@ -426,6 +426,7 @@ abstract class Maintenance {
                $this->addOption( 'server', "The protocol and server name to use in URLs, e.g. " .
                                "http://en.wikipedia.org. This is sometimes necessary because " .
                                "server name detection may fail in command line scripts.", false, true );
+               $this->addOption( 'profiler', 'Set to "text" or "trace" show profiling output', false, true );
 
                # Save generic options to display them separately in help
                $this->mGenericParameters = $this->mParams;
@@ -877,6 +878,16 @@ abstract class Maintenance {
                $wgShowSQLErrors = true;
                @set_time_limit( 0 );
                $this->adjustMemoryLimit();
+
+               // Per-script profiling; useful for debugging
+               $forcedProfiler = $this->getOption( 'profiler' );
+               if ( $forcedProfiler === 'text' ) {
+                       Profiler::setInstance( new ProfilerSimpleText( array() ) );
+                       Profiler::instance()->setTemplated( true );
+               } elseif ( $forcedProfiler === 'trace' ) {
+                       Profiler::setInstance( new ProfilerSimpleTrace( array() ) );
+                       Profiler::instance()->setTemplated( true );
+               }
        }
 
        /**
index ea4be82..9dba818 100644 (file)
@@ -21,9 +21,7 @@
  * @ingroup Maintenance
  */
 
-$wgProfiler = array( 'class' => 'ProfilerSimpleText' );
 error_reporting( E_ALL );
-
 require_once __DIR__ . '/Maintenance.php';
 
 /**
@@ -44,6 +42,8 @@ class TestFileOpPerformance extends Maintenance {
        }
 
        public function execute() {
+               Profiler::setInstance( new ProfilerSimpleText( array() ) ); // clear
+
                $backend = FileBackendGroup::singleton()->get( $this->getOption( 'b1' ) );
                $this->doPerfTest( $backend );
 
@@ -52,10 +52,8 @@ class TestFileOpPerformance extends Maintenance {
                        $this->doPerfTest( $backend );
                }
 
-               $profiler = Profiler::instance();
-               $profiler->setTemplated( true );
-
-               //NOTE: as of MW1.21, $profiler->logData() is called implicitly by doMaintenance.php.
+               Profiler::instance()->setTemplated( true );
+               // NOTE: as of MW1.21, $profiler->logData() is called implicitly by doMaintenance.php.
        }
 
        protected function doPerfTest( FileBackend $backend ) {