Beschleunigen Sie den Projektcache in NoVerify (Linter für PHP) zehnmal

Als Iskander eines Abends mit Iskander @quasilyte über die Schwierigkeiten bei der Entwicklung eines Linter für PHP in Go sprach , erwähnte er, dass Tests vor Ort lange dauern (ungefähr eine Minute, und es scheint mir, dass sie für Go ziemlich lang sind). Wir haben angefangen zu graben und es wurde schnell klar, dass die Tests, bei denen NoVerify (der Name des Linter) im Modus mit eingeschaltetem Renndetektor ausgeführt wird, hauptsächlich "langsamer" werden . Das phpstorm-stubs- Repository wird für jeden Start indiziert, das alle Definitionen der in PHP integrierten Funktionen / Klassen / Konstanten enthält, und die Indizierung dieses Repositorys auf einem 4-Core-Computer dauert ca. 4 Sekunden (ohne Race Detector ist alles viel schneller). Da es mehrere solcher Läufe gibt, einen für jedes getestete Open-Source-Projekt, kann die Gesamtausführungszeit aller Tests Minuten betragen. NoVerify positioniert sich als sehr schneller Linter für PHP, daher ist diese Leistung natürlich ein wenig traurig und es war notwendig, eine Lösung zu finden.

NoVerify-Architektur

Zunächst einmal lohnt es sich, ein wenig darüber zu sprechen, wie NoVerify funktioniert. Die Arbeit des Linters ist in zwei große Phasen unterteilt: Indizierung und direkte Analyse.

Projektindizierung bedeutet, dass Definitionen und Typen aller Funktionen, Klassen, Methoden, Konstanten und globalen Variablen aus allen PHP-Dateien extrahiert werden und alle diese Informationen für den schnellen Zugriff im RAM gespeichert werden. Diese Informationen werden auch im Gob- Format im Cache auf der Festplatte gespeichert , um zu vermeiden, dass das gesamte Projekt jedes Mal analysiert werden muss. Es ist wichtig, dass auch zur Analyse einer einzelnen Datei das gesamte Projekt indiziert werden mussDenn wenn es in PHP ein Autoload für Klassen gibt, gibt es für Funktionen, Konstanten und vor allem globale Variablen kein solches und sie können überall definiert werden. Natürlich werden in modernen PHP-Projekten normalerweise nur Klassen verwendet, und solche Probleme treten nicht auf, aber für Projekte mit einer langen Geschichte ist dies immer noch relevant. Die Notwendigkeit, das gesamte Projekt für seine Analyse zu indizieren, war der Grund für das Schreiben von NoVerify in Go, da diese Sprache Multithreading gut unterstützt, was bedeutet, dass das Projekt viel schneller indiziert werden kann, als dies in PHP möglich ist.

(, , ), . , , ( , phpstorm-stubs 90+% ). //, .

phpstorm-stubs

, , , , phpstorm-stubs, , , «» (.. ) // PHP, 25% , , . , : phpstorm-stubs «» , , , , , , .., , .

«» :

  1. , . , phpstorm-stubs .

  2. phpstorm-stubs , , .

  3. , gob.

  4. , phpstorm-stubs , Go- phpstorm-stubs . , , , 2-3 .

, (2), . , (1), , , . , , Go phpstorm-stubs ~200 (.. 20 ), , 18 , , .

?

, golden- , , , - . , , phpstorm-stubs. , -.

, ( Laravel, composer create-project --prefer-dist laravel/laravel blog, 1.6 PHP) 450 ( 4 ), NoVerify , , , , language server.

/

Go- 1.6 20-60 , , , , . .

: noverifyturbo 20 100 , ~80 1.6 PHP-.

, - NoVerify, , NoVerify. , .

-

: , Go- fmt.Printf("%#v", value).

Beispiel für generierten Code

, , , , GoStringer(), .

PHP- Go-, map[string]func()*PerFileCache, ( PHP- , , ), , PHP-. , , , , map ( - , ), , , , map , .

+ , , - stat() , .

Laravel 1.6 , composer create-project --prefer-dist laravel/laravel blog , :

  1. , 1 : 4

  2. -, 1 : 400

  3. , 12 : 1 (10 )

  4. -, 12 : 240 (800 )

, - , , - map , , . , - , , .

— , , , , ( Google, ).

NoVerify Go, , phpstorm-stubs «» . . , , NoVerify workflow , PHPStorm VS Code , .

  1. NoVerify — PHP .

  2. phpstorm-stubs — «» PHP .

  3. NoVerify

  4. phpstorm-stubs

  5. Vergleich verschiedener Datenserialisierungsformate in Go




All Articles