Acelere o cache do projeto no NoVerify (linter para PHP) 10 vezes

Uma noite, enquanto discutia as dificuldades de desenvolver um linter para PHP em Go com Iskander @quasilyte , Iskander mencionou que os testes demoram muito quando executados localmente (cerca de um minuto, e me parece que para Go é muito longo). Começamos a cavar e rapidamente ficou claro que os testes que executam NoVerify (o nome do linter) no modo com o detector de corrida ligado estão principalmente "diminuindo a velocidade" . O repositório phpstorm-stubs é indexado para cada lançamento, que contém todas as definições de funções / classes / constantes integradas que estão no PHP, e a indexação desse repositório leva cerca de 4 segundos em uma máquina de 4 núcleos (observe que sem um detector de corrida tudo é muito mais rápido). Como existem várias execuções, uma para cada projeto de código aberto testado, o tempo total de execução de todos os testes pode levar minutos. NoVerify se posiciona como um linter muito rápido para PHP, então, é claro, esse desempenho é um pouco triste e era necessário encontrar uma solução.

Arquitetura NoVerify

Para começar, ainda vale a pena falar um pouco sobre como funciona o NoVerify. O trabalho do linter divide-se em duas grandes fases: indexação e análise direta.

A indexação do projeto significa que as definições e tipos de todas as funções, classes, métodos, constantes e variáveis ​​globais são extraídos de todos os arquivos PHP, e todas essas informações são armazenadas na RAM para acesso rápido. Além disso, essas informações são salvas no cache do disco no formato gob para evitar a necessidade de analisar todo o projeto todas as vezes. É importante que mesmo para analisar um único arquivo, todo o projeto deve estar indexado, porque se houver um carregamento automático para classes em PHP, então não existe tal coisa para funções, constantes e ainda mais variáveis ​​globais, e elas podem ser definidas em qualquer lugar. Claro, em projetos PHP modernos, normalmente apenas classes são usadas e tais problemas não surgem, mas para projetos com uma longa história isso ainda é relevante. A necessidade de indexar todo o projeto para sua análise foi o motivo de escrever NoVerify em Go, uma vez que esta linguagem suporta multithreading bem, o que significa que será capaz de indexar o projeto muito mais rápido do que é possível em PHP.

(, , ), . , , ( , 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).

exemplo de código gerado

, , , , 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. Comparar diferentes formatos de serialização de dados em Go




All Articles