Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Make RuboCop Super Fast

Koichi ITO
September 09, 2022

Make RuboCop Super Fast

Koichi ITO

September 09, 2022
Tweet

More Decks by Koichi ITO

Other Decks in Programming

Transcript

  1. !LPJD w 044QSPHSBNNFS w 3VCP$PQDPSFUFBN TJODF  w )FBENBJOUBJOFSPG3VCP$PQ3BJMT 

    3VCP$PQ1FSGPSNBODF BOE 3VCP$PQ.JOJUFTU w &OHJOFFSJOH.BOBHFSBOE %JTUJOHVJTIFE&OHJOFFSPG&4. *OD
  2. 5IFpSTUDPNNJU % git log -p --reverse commit afbead34db54506c12a21dbd4ce04fada0f8b9a4 Author: Bozhidar

    Batsov <[email protected]> Date: Sat Apr 21 13:06:42 2012 +0300 Initial commit to rubocop. --- .document | 5 +++++ .gitignore | 49 +++++++++++++++++++++++++++++++++++++++ ++++++++++ .rspec | 1 + Gemfile | 16 ++++++++++++++++ LICENSE.txt | 20 ++++++++++++++++++++ README.rdoc | 19 +++++++++++++++++++ Rakefile | 45 +++++++++++++++++++++++++++++++++++++++ ++++++ features/rubocop.feature | 9 +++++++++ features/step_definitions/rubocop_steps.rb | 0 features/support/env.rb | 13 +++++++++++++
  3. 5IFpSTUDPNNJU % git log -p --reverse commit afbead34db54506c12a21dbd4ce04fada0f8b9a4 Author: Bozhidar

    Batsov <[email protected]> Date: Sat Apr 21 13:06:42 2012 +0300 Initial commit to rubocop. --- .document | 5 +++++ .gitignore | 49 +++++++++++++++++++++++++++++++++++++++ ++++++++++ .rspec | 1 + Gemfile | 16 ++++++++++++++++ LICENSE.txt | 20 ++++++++++++++++++++ README.rdoc | 19 +++++++++++++++++++ Rakefile | 45 +++++++++++++++++++++++++++++++++++++++ ++++++ features/rubocop.feature | 9 +++++++++ features/step_definitions/rubocop_steps.rb | 0 features/support/env.rb | 13 +++++++++++++ 👈
  4. .F

  5. DPSF$16T )ZQFS5ISFBEJOH TFD      OPQBSBMMFM QBSBMMFM

    w8IFO3VCP$PQ JOTQFDUTBMPUPG pMFT JUXJMMCF FGGFDUJWF wFHTFDTFD BCPVUpMFT
  6. YGBTUFSNPEVMFMPBEJOH TFD      SFRVJSFSVCPDPQ SFRVJSFSVCPDPQTFSWFS wrequire

    'rubocop' SFRVJSFTNPTUPGpMFT wrequire 'rubocop/ server'POMZSFRVJSFT pMFTOFFEFEGPS TFSWFSNPEF
  7. 3VCP$PQQSPDFTT 1*% *OTJEFUSBEJUJPOBMrubocopDPNNBOE # exe/rubocop (snip) require 'rubocop' RuboCop::CLI.new.run •RuboCop::CLI.new.runJTBOFOEQPJOU"1*

    w&BDICPPUrubocopQSPDFTTSVOTSVCPDPQDPNNBOE # Term #1 % rubocop # Term #2 % rubocop 4UBSUBOESVO 3VCP$PQQSPDFTT 1*% # exe/rubocop (snip) require 'rubocop' RuboCop::CLI.new.run 4UBSUBOESVO
  8. 3VCP$PQQSPDFTT 1*% *OTJEFUSBEJUJPOBMrubocopDPNNBOE # exe/rubocop (snip) require 'rubocop' RuboCop::CLI.new.run •RuboCop::CLI.new.runJTBOFOEQPJOU"1*

    w&BDICPPUrubocopQSPDFTTSVOTSVCPDPQDPNNBOE # Term #1 % rubocop # Term #2 % rubocop # Term #3 % rubocop 4UBSUBOESVO 4UBSUBOESVO 3VCP$PQQSPDFTT 1*% # exe/rubocop (snip) require 'rubocop' RuboCop::CLI.new.run 3VCP$PQQSPDFTT 1*% # exe/rubocop (snip) require 'rubocop' RuboCop::CLI.new.run 4UBSUBOESVO
  9. 3VCP$PQQSPDFTT 1*% *OTJEFUSBEJUJPOBMrubocopDPNNBOE # exe/rubocop (snip) require 'rubocop' RuboCop::CLI.new.run •RuboCop::CLI.new.runJTBOFOEQPJOU"1*

    w&BDICPPUrubocopQSPDFTTSVOTSVCPDPQDPNNBOE # Term #1 % rubocop # Term #2 % rubocop # Term #3 % rubocop 4UBSUBOESVO 4UBSUBOESVO 3VCP$PQQSPDFTT 1*% # exe/rubocop (snip) require 'rubocop' RuboCop::CLI.new.run 3VCP$PQQSPDFTT 1*% # exe/rubocop (snip) require 'rubocop' RuboCop::CLI.new.run 1*%TBSFBMXBZTEJ⒎FSFOU 4UBSUBOESVO
  10. $MJFOU1SPDFTT 1*% 4UBSU%BFNPO 4FSWFS 4FSWFS1SPDFTT 1*% # Loading dependencies. require

    'rubocop' TCPServer.open('127.0.0.1', port) Process.daemon(true) rubocop-daemon % rubocop-daemon start rubocop rubocop-daemon startTUBSUTTFSWFSQSPDFTT
  11. $MJFOU1SPDFTT 1*% 4UBSU%BFNPO 4FSWFS 4FSWFS1SPDFTT 1*% # Loading dependencies. require

    'rubocop' TCPServer.open('127.0.0.1', port) Process.daemon(true) rubocop-daemon % rubocop-daemon start rubocop rubocop-daemon startTUBSUTUIFQSPDFTTBTEBFNPO Process.daemon(true)
  12. 6QBOESVOOJOH $MJFOU1SPDFTT 1*% 4UBSU%BFNPO 4FSWFS 4FSWFS1SPDFTT 1*% # Loading dependencies.

    require 'rubocop' TCPServer.open('127.0.0.1', port) Process.daemon(true) rubocop-daemon % rubocop-daemon start rubocop rubocop-daemon startTUBSUTUIFQSPDFTTBTEBFNPO Process.daemon(true)
  13. 6QBOESVOOJOH $MJFOU1SPDFTT 1*% &YFD3VCP$PQ 7JBDMJFOU 4FSWFS1SPDFTT 1*% # Loaded API

    RuboCop::CLI.new.run rubocop-daemon % rubocop-daemon exec rubocop rubocop-daemon execSVOTCLI.new.run PGEBFNPO TCP/IP TCPSocket.open('127.0.0.1', port)
  14. 6QBOESVOOJOH $MJFOU1SPDFTT 1*% &YFD3VCP$PQ 7JBDMJFOU 4FSWFS1SPDFTT 1*% # Loaded API

    RuboCop::CLI.new.run rubocop-daemon % rubocop-daemon exec $MJFOU1SPDFTT 1*% % rubocop-daemon exec rubocop $POUJOVFUPDPOOFDUUPUIFBMSFBEZSVOOJOHEBFNPO TCP/IP TCP/IP
  15. 6QBOESVOOJOH $MJFOU1SPDFTT 1*% &YFD3VCP$PQ 7JBDMJFOU 4FSWFS1SPDFTT 1*% # Loaded API

    RuboCop::CLI.new.run rubocop-daemon % rubocop-daemon exec $MJFOU1SPDFTT 1*% % rubocop-daemon exec rubocop $POUJOVFUPDPOOFDUUPUIFBMSFBEZSVOOJOHEBFNPO "MXBZTUIFTBNF1*% TCP/IP TCP/IP
  16. SVCPDPQEBFNPOXSBQQFS 4FSWFS1SPDFTT QJE require 'rubocop' TCPServer.open('127.0.0.1', port) Process.daemon(true) rubocop-daemon-wrapper rubocop

    5IFTIFMMTDSJQUTUBSUTUIFEBFNPOJGJUJTOPUSVOOJOH $MJFOU1SPDFTT QJE if [ ! -f "$TOKEN_PATH" ]; then $RUBOCOP_DAEMON start fi # snip if ! run_rubocop_command $@; then RuboCop::CLI.new.run # ~/.bashrc export PATH="/usr/local/bin/rubocop-daemon-wrapper:$PATH" ncDNE  
  17. 4FSWFS1SPDFTT QJE require 'rubocop' TCPServer.open('127.0.0.1', port) Process.daemon(true) SVCPDPQEBFNPOXSBQQFS rubocop-daemon-wrapper rubocop

    5IFTIFMMTDSJQUTUBSUTUIFEBFNPOJGJUJTOPUSVOOJOH $MJFOU1SPDFTT QJE if [ ! -f "$TOKEN_PATH" ]; then $RUBOCOP_DAEMON start fi # snip if ! run_rubocop_command $@; then RuboCop::CLI.new.run # ~/.bashrc export PATH="/usr/local/bin/rubocop-daemon-wrapper:$PATH" ncDNE   $RUBOCOP_DAEMON start require 'rubocop' TCPServer.open('127.0.0.1', port) Process.daemon(true)
  18. SVCPDPQEBFNPOXSBQQFS 4FSWFS1SPDFTT QJE require 'rubocop' TCPServer.open('127.0.0.1', port) Process.daemon(true) rubocop-daemon-wrapper rubocop

    5IFTIFMMTDSJQUTUBSUTUIFEBFNPOJGJUJTOPUSVOOJOH $MJFOU1SPDFTT QJE if [ ! -f "$TOKEN_PATH" ]; then $RUBOCOP_DAEMON start fi # snip if ! run_rubocop_command $@; then RuboCop::CLI.new.run # ~/.bashrc export PATH="/usr/local/bin/rubocop-daemon-wrapper:$PATH" ncDNE   run_rubocop_command RuboCop::CLI.new.run
  19. SVCPDPQEBFNPOXSBQQFS 4FSWFS1SPDFTT QJE require 'rubocop' TCPServer.open('127.0.0.1', port) Process.daemon(true) rubocop-daemon-wrapper rubocop

    5IFTIFMMTDSJQUTUBSUTUIFEBFNPOJGJUJTOPUSVOOJOH $MJFOU1SPDFTT QJE if [ ! -f "$TOKEN_PATH" ]; then $RUBOCOP_DAEMON start fi # snip if ! run_rubocop_command $@; then RuboCop::CLI.new.run # ~/.bashrc export PATH="/usr/local/bin/rubocop-daemon-wrapper:$PATH" ncDNE   # ~/.bashrc export PATH="/usr/local/bin/rubocop-daemon-wrapper:$PATH"
  20. $MJFOU1SPDFTT 1*% "CPVUUIFTFSWFSNPEF 4FSWFS1SPDFTT 1*% require 'rubocop/server' server_cli = RuboCop::Server::CLI.new

    exit_status = server_cli.run exit exit_status if server_cli.exit? if RuboCop::Server.running? exit_status = RuboCop::Server::ClientCommand::Exec.new.run else require 'rubocop' cli = RuboCop::CLI.new.run end client process % rubocop --server server process 4UBSUTFSWFSQSPDFTTFTBOEJOTQFDUTPVSDFDPEF
  21. $MJFOU1SPDFTT 1*% "CPVUUIFTFSWFSNPEF 4FSWFS1SPDFTT 1*% require 'rubocop/server' server_cli = RuboCop::Server::CLI.new

    exit_status = server_cli.run exit exit_status if server_cli.exit? if RuboCop::Server.running? exit_status = RuboCop::Server::ClientCommand::Exec.new.run else require 'rubocop' cli = RuboCop::CLI.new.run end client process % rubocop --server $MJFOU1SPDFTT 1*% % rubocop --server server process $POUJOVFUPDPOOFDUUPBOBMSFBEZSVOOJOHTFSWFS "MXBZTUIFTBNFQSPDFTT
  22. YGBTUFSNPEVMFMPBEJOH TFD      SFRVJSFSVCPDPQ SFRVJSFSVCPDPQTFSWFS wrequire

    'rubocop' SFRVJSFTNPTUPGpMFT wrequire 'rubocop/ server'POMZSFRVJSFT pMFTOFFEFEGPS TFSWFSNPEF
  23. YGBTUFS % ruby -rbenchmark -e '$LOAD_PATH.unshift("/path/to/rubocop/lib"); Benchmark.bm { |x| x.report

    { require "rubocop" }}' user system total real 0.573636 0.217166 0.790802 ( 0.815585) % ruby -rbenchmark -e '$LOAD_PATH.unshift("/path/to/rubocop/lib"); Benchmark.bm { |x| x.report { require "rubocop/server" }}' user system total real 0.000386 0.000587 0.000973 ( 0.000969) SFRVJSFSVCPDPQ SFRVJSFSVCPDPQTFSWFS
  24. $VSSFOUexe/rubocop "GUFS require 'rubocop/server' server_cli = RuboCop::Server::CLI.new exit_status = server_cli.run

    exit exit_status if server_cli.exit? if RuboCop::Server.running? exit_status = RuboCop::Server::ClientCommand::Exec.new.run else require 'rubocop' cli = RuboCop::CLI.new.run end $PEFTOJQQFU .BLFBMJHIUXFJHIUEFQFOEFODZSFRVJSF require 'rubocop/server'
  25. $VSSFOUexe/rubocop "GUFS require 'rubocop/server' server_cli = RuboCop::Server::CLI.new exit_status = server_cli.run

    exit exit_status if server_cli.exit? if RuboCop::Server.running? exit_status = RuboCop::Server::ClientCommand::Exec.new.run else require 'rubocop' cli = RuboCop::CLI.new.run end $PEFTOJQQFU .BLFBMJHIUXFJHIUEFQFOEFODZSFRVJSF 4FSWFSNPEFTFUVQ FHTUBSUJOHBOETUPQQJOH server_cli = RuboCop::Server::CLI.new exit_status = server_cli.run exit exit_status if server_cli.exit?
  26. $VSSFOUexe/rubocop "GUFS require 'rubocop/server' server_cli = RuboCop::Server::CLI.new exit_status = server_cli.run

    exit exit_status if server_cli.exit? if RuboCop::Server.running? exit_status = RuboCop::Server::ClientCommand::Exec.new.run else require 'rubocop' cli = RuboCop::CLI.new.run end $PEFTOJQQFU .BLFBMJHIUXFJHIUEFQFOEFODZSFRVJSF 4FSWFSNPEFTFUVQ FHTUBSUJOHBOETUPQQJOH $IFDLTFSWFSTUBUVT if RuboCop::Server.running?
  27. $VSSFOUexe/rubocop "GUFS require 'rubocop/server' server_cli = RuboCop::Server::CLI.new exit_status = server_cli.run

    exit exit_status if server_cli.exit? if RuboCop::Server.running? exit_status = RuboCop::Server::ClientCommand::Exec.new.run else require 'rubocop' cli = RuboCop::CLI.new.run end $PEFTOJQQFU .BLFBMJHIUXFJHIUEFQFOEFODZSFRVJSF 4FSWFSNPEFTFUVQ FHTUBSUJOHBOETUPQQJOH $IFDLTFSWFSTUBUVT 3VOOJOHXJUITFSWFSNPEF exit_status = RuboCop::Server::ClientCommand::Exec.new.run
  28. $VSSFOUexe/rubocop "GUFS require 'rubocop/server' server_cli = RuboCop::Server::CLI.new exit_status = server_cli.run

    exit exit_status if server_cli.exit? if RuboCop::Server.running? exit_status = RuboCop::Server::ClientCommand::Exec.new.run else require 'rubocop' cli = RuboCop::CLI.new.run end $PEFTOJQQFU .BLFBMJHIUXFJHIUEFQFOEFODZSFRVJSF 4FSWFSNPEFTFUVQ FHTUBSUJOHBOETUPQQJOH $IFDLTFSWFSTUBUVT 3VOOJOHXJUIOPTFSWFSNPEF 3VOOJOHXJUITFSWFSNPEF require 'rubocop' cli = RuboCop::CLI.new.run
  29. $VSSFOUexe/rubocop "GUFS require 'rubocop/server' server_cli = RuboCop::Server::CLI.new exit_status = server_cli.run

    exit exit_status if server_cli.exit? if RuboCop::Server.running? exit_status = RuboCop::Server::ClientCommand::Exec.new.run else require 'rubocop' cli = RuboCop::CLI.new.run end $PEFTOJQQFU .BLFBMJHIUXFJHIUEFQFOEFODZSFRVJSF 4FSWFSNPEFTFUVQ FHTUBSUJOHBOETUPQQJOH $IFDLTFSWFSTUBUVT 3VOOJOHXJUIOPTFSWFSNPEF 3VOOJOHXJUITFSWFSNPEF require 'rubocop' cli = RuboCop::CLI.new.run 4MPX
  30. .VDIMJHIUFSUIBOrequire 'rubocop' require 'rubocop/server' server_cli = RuboCop::Server::CLI.new exit_status = server_cli.run

    exit exit_status if server_cli.exit? if RuboCop::Server.running? exit_status = RuboCop::Server::ClientCommand::Exec.new.run else require 'rubocop' cli = RuboCop::CLI.new.run end $PEFTOJQQFU .BLFBMJHIUXFJHIUEFQFOEFODZSFRVJSF 4FSWFSNPEFTFUVQ FHTUBSUJOHBOETUPQQJOH $IFDLTFSWFSTUBUVT 3VOOJOHXJUITFSWFSNPEF server_cli = RuboCop::Server::CLI.new exit_status = server_cli.run exit exit_status if server_cli.exit? exit_status = RuboCop::Server::ClientCommand::Exec.new.run require 'rubocop/server' if RuboCop::Server.running?
  31. $MJFOU1SPDFTT 1*% &YFD3VCP$PQXJUITFSWFS 4FSWFS1SPDFTT 1*% require 'rubocop/server' server_cli = RuboCop::Server::CLI.new

    exit_status = server_cli.run exit exit_status if server_cli.exit? if RuboCop::Server.running? exit_status = RuboCop::Server::ClientCommand::Exec.new.run else require 'rubocop' cli = RuboCop::CLI.new.run end rubocop client % rubocop --server $MJFOU1SPDFTT 1*% % rubocop --server rubocop server $POUJOVFUPDPOOFDUUPBOBMSFBEZSVOOJOHTFSWFS "MXBZTUIFTBNFQSPDFTT
  32. *NQPSUFESVCPDPQEBFNPOPQUJPOT SVCPDPQEBFNPO SVCPDPQ OPUF FYFD rubocop-daemon exec rubocop --server rubocopJTBMTP0,BGUFS

    TUBSUJOHUIFTFSWFS FYFDXP TFSWFS N/A rubocop --no-server %FGBVMUXJUIPVUTFSWFS PQUJPOT TUBSUTFSWFS rubocop-daemon start rubocop --start-server )PTUBOEQPSUDBOCF TQFDJpFEXJUIFOWWBST TUPQTFSWFS rubocop-daemon stop rubocop --stop-server SFTUBSU rubocop-daemon restart rubocop --restart-server TUBUVT rubocop-daemon status rubocop --server-status TUBSUFYFD rubocop-daemon-wrapper rubocop --server
  33. w4FSWFSQSPDFTTOBNFJT rubocop --server #{dirname} w3VCP$PQTFSWFSTBSFBTTPDJBUFEXJUI UIFEJSFDUPSZJOXIJDIUIFZXFSFTUBSUFE 4FSWFSQSPDFTTOBNF % ps aux

    | grep 'rubocop --server' user 16060 0.0 0.0 5078568 2264 ?? S 7:54AM 0:00.00 rubocop --server /Users/koic/src/github.com/esminc/foo user 16337 0.0 0.0 5331560 2396 ?? S 23:51PM 0:00.00 rubocop --server /Users/koic/src/github.com/esminc/bar
  34. w:PVDBOBMTPDPOpSNrubocop -V w+serverJTBEEFE w-VPQUJPOQSPWJEFTJOGPVTFEJOJTTVFSFQPSUT w-JLFruby -vGPSFOBCMF:+*5 +YJITJTBEEFE rubocop -V -BSHF7

    % ruby --yjit -ve 'RubyVM::YJIT.enabled?' ruby 3.2.0dev (2022-09-08T05:31:42Z master 78af05ba0f) +YJIT [x86_64-darwin19] % rubocop -V 1.36.0 (using Parser 3.1.2.1, rubocop-ast 1.21.0, running on ruby 3.2.0) +server [x86_64-darwin19]
  35. DBDIFSVCPDPQ@DBDIFTFSWFS $MJFOU1SPDFTT 1*% OE&YFDUIFTFSWFS 4FSWFS1SPDFTT 1*% % rubocop --server 3FBEQJE

    QPSU WFSTJPO BOEPUIFSTUPDBDIFpMFT QJE QPSU WFSTJPO $MJFOU1SPDFTT 1*% % rubocop (--server) Disk IO client server
  36. DBDIFSVCPDPQ@DBDIFTFSWFS $MJFOU1SPDFTT 1*% 5IFDBDIFEJSFDUPSZ 4FSWFS1SPDFTT 1*% % rubocop --server 3FTUBSUUIFQSPDFTTXIFOBGUFSbundle

    update QJE QPSU WFSTJPO $MJFOU1SPDFTT 1*% % rubocop (--server) 5IFDMJFOUDPNNBOESFTUBSUTUIFTFSWFS QSPDFTTJGJUEFUFDUTJODPNQBUJCMFWFSTJPO client server