Addshore has uploaded a new change for review.

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

Change subject: Speed up PHP_CodeSniffer_Sniff
......................................................................

Speed up PHP_CodeSniffer_Sniff

This causes 1 scan of all tokens in a file looking
for namespaces where as before one would have been
done for EVERY method in the file.

While profiling on the Title file in mwcore
the tokenIsNamespaced accounted for 22% of execution
time while running phpcs on the file.

After this refactoring tokenIsNamespaced only accounts
for 0.2% of the time in this file.

This is from 2313ms to 23ms.

In its current form of course the static arrays will grow
throughout the phpcs run but I don't really see that becoming
a major issue.
Auto cleanup of the arrays through the phpcs run would be easy
but best not to both until this is needed as we want speed here!

Change-Id: I4cd5cbed47d24a6c3a655e0225d0722f764f7c69
---
M MediaWiki/Sniffs/NamingConventions/PrefixedGlobalFunctionsSniff.php
1 file changed, 52 insertions(+), 10 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/tools/codesniffer 
refs/changes/01/286301/1

diff --git 
a/MediaWiki/Sniffs/NamingConventions/PrefixedGlobalFunctionsSniff.php 
b/MediaWiki/Sniffs/NamingConventions/PrefixedGlobalFunctionsSniff.php
index f2c7481..cbedd56 100644
--- a/MediaWiki/Sniffs/NamingConventions/PrefixedGlobalFunctionsSniff.php
+++ b/MediaWiki/Sniffs/NamingConventions/PrefixedGlobalFunctionsSniff.php
@@ -15,17 +15,59 @@
                return [ T_FUNCTION ];
        }
 
-       public function process( PHP_CodeSniffer_File $phpcsFile, $stackPtr ) {
-               $tokens = $phpcsFile->getTokens();
-               $ptr = $stackPtr;
-               while ( $ptr > 0 ) {
-                       $token = $tokens[$ptr];
-                       if ( $token['type'] === "T_NAMESPACE" && !isset( 
$token['scope_opener'] ) ) {
-                               // In the format of "namespace Foo;", which 
applies to the entire file
-                               return;
-                       }
-                       $ptr--;
+       /**
+        * @var int[] array containing the first locations of namespaces in 
files that we have seen so far.
+        */
+       private static $firstNamespaceLocations = array();
+
+       /**
+        * @var string[] array containing a list of files that contain no 
namespace statements.
+        */
+       private static $noNamespaceFiles = array();
+
+       /**
+        * @param PHP_CodeSniffer_File $phpcsFile
+        * @param int $ptr
+        * @return bool Does a namespace statement exist before this position 
in the file?
+        */
+       private function tokenIsNamespaced( PHP_CodeSniffer_File $phpcsFile, 
$ptr ) {
+               $fileName = $phpcsFile->getFilename();
+               // Check if we already know if the token is namespaced or not 
and return early if possible.
+               if( isset( self::$firstNamespaceLocations[$fileName] ) && $ptr 
> self::$firstNamespaceLocations[$fileName] ) {
+                       return true;
                }
+               if( isset( self::$noNamespaceFiles[$fileName] ) ) {
+                       return false;
+               }
+
+               // If not scan the whole file at once looking for namespacing 
or lack of and set in the statics.
+               $tokens = $phpcsFile->getTokens();
+               $tokenIndex = max( array_keys( $tokens ) );
+               while ( $tokenIndex > 0 ) {
+                       $token = $tokens[$tokenIndex];
+                       if ( $token['type'] === "T_NAMESPACE" && !isset( 
$token['scope_opener'] ) ) {
+                               // In the format of "namespace Foo;", which 
applies to everything below
+                               self::$firstNamespaceLocations[$fileName] = 
$tokenIndex;
+                       }
+                       $tokenIndex--;
+               }
+               if( !isset( self::$firstNamespaceLocations[$fileName] ) ) {
+                       self::$noNamespaceFiles[$fileName] = true;
+               }
+
+               // Return if the token was namespaced.
+               if( isset( self::$firstNamespaceLocations[$fileName] ) && $ptr 
> self::$firstNamespaceLocations[$fileName] ) {
+                       return true;
+               }
+               return false;
+       }
+
+       public function process( PHP_CodeSniffer_File $phpcsFile, $stackPtr ) {
+               if( $this->tokenIsNamespaced( $phpcsFile, $stackPtr ) ) {
+                       return;
+               }
+
+               $tokens = $phpcsFile->getTokens();
                $token = $tokens[$stackPtr];
 
                // Name of function

-- 
To view, visit https://gerrit.wikimedia.org/r/286301
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I4cd5cbed47d24a6c3a655e0225d0722f764f7c69
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/tools/codesniffer
Gerrit-Branch: master
Gerrit-Owner: Addshore <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to