将NoVerify(适用于PHP的Linter)中的项目缓存加速10倍

一天晚上,在讨论使用Iskander @quasilyte在Go中为PHP开发一个linter的困难时,Iskander提到测试在本地运行需要很长时间(大约一分钟,在我看来,Go相当长)。我们开始进行挖掘,很快就发现,在打开种族检测器的模式下运行NoVerify(短绒的名称)的测试主要是“慢下来” 每次启动都会为phpstorm-stubs存储库建立索引,其中包含PHP中内置函数/类/常量的所有定义,并且在4核计算机上对该存储库建立索引大约需要4秒钟(请注意,如果没有竞争检测器,一切都会更快)。由于有多个这样的运行,每个测试的开源项目一个,因此所有测试的总执行时间可能需要几分钟。NoVerify将自己定位为PHP的非常快速的学习者,因此,这种性能当然让人有些难过,因此有必要找到一些解决方案。

NoVerify体系结构

首先,还是值得谈论一下NoVerify的工作原理。皮特工作分为两个主要阶段:索引编制和直接分析。

项目索引意味着从所有PHP文件中提取所有函数,类,方法,常量和全局变量的定义和类型,并将所有这些信息存储在RAM中以便快速访问。该信息也以gob格式存储在磁盘上的高速缓存中,以避免每次都需要解析整个项目。 即使分析单个文件,也必须对整个项目建立索引,这一点很重要。,因为如果PHP中有自动加载类的功能,则函数,常量甚至全局变量都没有这种功能,并且可以在任何地方定义它们。当然,在现代PHP项目中,通常仅使用类,并且不会出现此类问题,但是对于历史悠久的项目而言,这仍然很重要。在Go中编写NoVerify的原因是需要对整个项目进行索引,这是因为该语言很好地支持多线程,这意味着它将能够比在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).

生成代码示例

, , , , 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. 在Go中比较不同的数据序列化格式




All Articles