valid,invalid

関心を持てる事柄について

zshの起動が遅かったのでzprofでプロファイリングしながら起動速度を3倍速くした

(追記: 2021-07-18) 本記事の続編 => zshの起動がいつの間にか速くなっていた - valid,invalid

zshの起動速度が遅いのをずっと放置していたので改善した。もともと遅かったので自慢できる数字ではないが、とても大雑把に言うと起動時間がおよそ3秒→1秒と3倍速くなった

やったこと

zprofでボトルネック特定

今回はこの方法を知ることが出来たので一番の収穫だったかもしれない。

まず、単純にtimeコマンドで計測するとおおまかな処理時間はわかるが、ボトルネックがわからない。

# チューニング前の time コマンド実行結果
❯ for i in $(seq 1 10); do time zsh -i -c exit; done
zsh -i -c exit  1.84s user 1.29s system 103% cpu 3.013 total
zsh -i -c exit  1.90s user 1.32s system 103% cpu 3.119 total
zsh -i -c exit  1.96s user 1.37s system 103% cpu 3.199 total
zsh -i -c exit  1.92s user 1.30s system 104% cpu 3.092 total
zsh -i -c exit  2.04s user 1.49s system 102% cpu 3.445 total
zsh -i -c exit  1.90s user 1.34s system 103% cpu 3.140 total
zsh -i -c exit  1.90s user 1.29s system 103% cpu 3.073 total
zsh -i -c exit  2.23s user 1.53s system 91% cpu 4.109 total
zsh -i -c exit  2.35s user 1.91s system 84% cpu 5.025 total
zsh -i -c exit  2.01s user 1.53s system 101% cpu 3.493 total

zsh 起動 遅い」等でググるzprofなるものが提供されているとわかった。zshの起動が遅いのでなんとかしたい - Qiita に従って.zshenvの最初と.zshrcの最後に以下を付け足す。

# .zshenv
zmodload zsh/zprof && zprof
# .zshrc
if (which zprof > /dev/null 2>&1) ;then
  zprof
fi

すると起動時にプロファイル結果が出力される。長いので詳細は省略している。

num  calls                time                       self            name
-----------------------------------------------------------------------------------
 1)    6        2320.87   386.81   68.33%    907.63   151.27   26.72%  pmodload
 2)    2         888.63   444.32   26.16%    888.32   444.16   26.16%  nvm_die_on_prefix
 3)    2        1916.71   958.35   56.44%    449.40   224.70   13.23%  nvm_auto
 4)    1         372.65   372.65   10.97%    372.25   372.25   10.96%  __kubectl_bash_source
 5)    4        1467.30   366.83   43.20%    356.07    89.02   10.48%  nvm
 6)    2         222.32   111.16    6.55%    198.99    99.50    5.86%  nvm_ensure_version_installed
 7)    1          74.28    74.28    2.19%     73.80    73.80    2.17%  _zsh_highlight_load_highlighters
 8)    2          29.95    14.97    0.88%     29.95    14.97    0.88%  compaudit
 9)    1          25.38    25.38    0.75%     25.38    25.38    0.75%  -zcache-hook-antigen
10)    2          23.32    11.66    0.69%     23.32    11.66    0.69%  nvm_is_version_installed
11)    2          16.74     8.37    0.49%     16.74     8.37    0.49%  nvm_supports_source_options
12)    2          41.45    20.73    1.22%     11.51     5.75    0.34%  compinit
13)   21          10.90     0.52    0.32%     10.90     0.52    0.32%  (anon)
14)    2           9.60     4.80    0.28%      9.60     4.80    0.28%  promptinit
15)    1           6.95     6.95    0.20%      6.95     6.95    0.20%  _zsh_highlight_bind_widgets
16)    1           4.06     4.06    0.12%      4.06     4.06    0.12%  async_init
17)    2           8.09     4.05    0.24%      2.22     1.11    0.07%  prompt_pure_setup
18)   12           1.79     0.15    0.05%      1.79     0.15    0.05%  add-zsh-hook
19)    2           5.55     2.77    0.16%      1.48     0.74    0.04%  async
20)    1           1.47     1.47    0.04%      1.47     1.47    0.04%  colors
21)    3           0.87     0.29    0.03%      0.87     0.29    0.03%  is-at-least
22)    1           0.78     0.78    0.02%      0.78     0.78    0.02%  -antigen-interactive-mode
23)    4           0.65     0.16    0.02%      0.65     0.16    0.02%  compdef
24)    4           0.59     0.15    0.02%      0.59     0.15    0.02%  nvm_has
25)    2        1933.81   966.91   56.94%      0.36     0.18    0.01%  nvm_process_parameters
26)    1           8.84     8.84    0.26%      0.20     0.20    0.01%  set_prompt
27)    4           0.19     0.05    0.01%      0.19     0.05    0.01%  -set-default
28)    1           5.57     5.57    0.16%      0.16     0.16    0.00%  -antigen-env-setup
29)    1           0.40     0.40    0.01%      0.15     0.15    0.00%  complete
30)    1           0.18     0.18    0.01%      0.12     0.12    0.00%  -zcache-antigen
31)    1          25.48    25.48    0.75%      0.10     0.10    0.00%  zcache-start
32)    2           0.23     0.12    0.01%      0.09     0.05    0.00%  -zcache-antigen-hook
33)    1           8.90     8.90    0.26%      0.06     0.06    0.00%  prompt
34)    1           0.04     0.04    0.00%      0.04     0.04    0.00%  bashcompinit
35)    1           0.04     0.04    0.00%      0.04     0.04    0.00%  is-callable
36)    2           0.03     0.02    0.00%      0.03     0.02    0.00%  nvm_is_zsh
37)    1           0.26     0.26    0.01%      0.03     0.03    0.00%  antigen
38)    1           0.06     0.06    0.00%      0.02     0.02    0.00%  antigen-bundle

nvm関連とpmodload関連の処理が重いとわかった。

nvm.sh を遅延ロードしてシェルの起動を高速化

NVM の nvm.sh を遅延ロードしてシェルの起動を高速化する - Qiita

↑の記事の対応をそのまま行ったところ、0.5~0.8秒ほどの改善が見られた。

❯ for i in $(seq 1 10); do time zsh -i -c exit; donezsh -i -c exit  1.46s user 1.01s system 99% cpu 2.480 total
zsh -i -c exit  1.42s user 0.95s system 100% cpu 2.364 total
zsh -i -c exit  1.42s user 0.96s system 100% cpu 2.372 total
zsh -i -c exit  1.43s user 0.97s system 98% cpu 2.431 total
zsh -i -c exit  1.44s user 0.97s system 95% cpu 2.539 total
zsh -i -c exit  1.46s user 0.98s system 100% cpu 2.429 total
zsh -i -c exit  1.38s user 0.97s system 103% cpu 2.278 total
zsh -i -c exit  1.38s user 0.95s system 103% cpu 2.242 total
zsh -i -c exit  1.40s user 0.93s system 104% cpu 2.223 total
zsh -i -c exit  1.41s user 0.91s system 104% cpu 2.219 total
num  calls                time                       self            name
-----------------------------------------------------------------------------------
 1)    6        1738.74   289.79   81.14%    610.52   101.75   28.49%  pmodload
 2)    1         984.57   984.57   45.95%    401.19   401.19   18.72%  nvm_auto
 3)    1         362.83   362.83   16.93%    362.45   362.45   16.91%  __kubectl_bash_source
 4)    1         302.44   302.44   14.11%    302.29   302.29   14.11%  nvm_die_on_prefix
 5)    2         583.38   291.69   27.23%    170.47    85.23    7.96%  nvm
 6)    1         110.33   110.33    5.15%     97.92    97.92    4.57%  nvm_ensure_version_installed
 7)    1          69.76    69.76    3.26%     69.33    69.33    3.24%  _zsh_highlight_load_highlighters
 8)    1          29.12    29.12    1.36%     29.12    29.12    1.36%  -zcache-hook-antigen
 9)    2          28.16    14.08    1.31%     28.16    14.08    1.31%  compaudit
10)    1          12.41    12.41    0.58%     12.41    12.41    0.58%  nvm_is_version_installed
11)    2          40.29    20.14    1.88%     12.13     6.06    0.57%  compinit
12)   21          10.97     0.52    0.51%     10.97     0.52    0.51%  (anon)
13)    2           9.25     4.62    0.43%      9.25     4.62    0.43%  promptinit
14)    1           8.08     8.08    0.38%      8.08     8.08    0.38%  nvm_supports_source_options
15)    1           6.63     6.63    0.31%      6.63     6.63    0.31%  _zsh_highlight_bind_widgets
16)    1           3.20     3.20    0.15%      3.20     3.20    0.15%  async_init
17)   12           1.81     0.15    0.08%      1.81     0.15    0.08%  add-zsh-hook
18)    1           1.21     1.21    0.06%      1.21     1.21    0.06%  colors
19)    2           5.35     2.68    0.25%      1.02     0.51    0.05%  prompt_pure_setup
20)    3           0.81     0.27    0.04%      0.81     0.27    0.04%  is-at-least
21)    4           0.71     0.18    0.03%      0.71     0.18    0.03%  compdef
22)    2           3.90     1.95    0.18%      0.71     0.35    0.03%  async
23)    1           0.34     0.34    0.02%      0.34     0.34    0.02%  -antigen-interactive-mode
24)    2           0.30     0.15    0.01%      0.30     0.15    0.01%  nvm_has
25)    1         992.92   992.92   46.34%      0.27     0.27    0.01%  nvm_process_parameters
26)    4           0.21     0.05    0.01%      0.21     0.05    0.01%  -set-default
27)    1           6.11     6.11    0.29%      0.21     0.21    0.01%  set_prompt
28)    2           0.38     0.19    0.02%      0.18     0.09    0.01%  -zcache-antigen-hook
29)    1           6.42     6.42    0.30%      0.18     0.18    0.01%  -antigen-env-setup
30)    1           0.26     0.26    0.01%      0.16     0.16    0.01%  -zcache-antigen
31)    1          29.28    29.28    1.37%      0.16     0.16    0.01%  zcache-start
32)    1           0.38     0.38    0.02%      0.14     0.14    0.01%  complete
33)    1           0.43     0.43    0.02%      0.06     0.06    0.00%  antigen
34)    1           0.05     0.05    0.00%      0.05     0.05    0.00%  is-callable
35)    1           6.16     6.16    0.29%      0.05     0.05    0.00%  prompt
36)    1           0.04     0.04    0.00%      0.04     0.04    0.00%  bashcompinit
37)    1           0.09     0.09    0.00%      0.03     0.03    0.00%  antigen-bundle
38)    1           0.01     0.01    0.00%      0.01     0.01    0.00%  nvm_is_zsh

しかし見てみると、nvm関連の処理がまだまだ存在している… 奴はすでに葬ったはずでは…?

ここまでの変更は Lazy load nvm · ohbarye/dotfiles@5b0653b · GitHub である。

preztoのmodule読み込みで対象を減らした

プロファイラの結果をよくみると、nvm_autonvm_die_on_prefixといった処理はpmodloadから呼ばれているとわかった。

pmodloadが何をしているかというと、.zpreztorcの定義にしたがってpreztoのmoduleをloadする。名前そのままだ。

# .zpreztorc
zstyle ':prezto:load' pmodule \
  'environment' \
  ... # つづく

ここでloadしているmoduleにnodeがあったのでこれを消すと途端に速度が上がった。

この他にも使わないmoduleがないかを確認していき、ひとつずつ消していった結果のcommit: Do not load unused modules given by prezto · ohbarye/dotfiles@70fa79e · GitHub

各moduleが何をしているのかパッと見てはわからないので、https://github.com/sorin-ionescu/prezto/tree/master/modulesから一つずつ確認した。中には読んでもわからないものがあったので、一度そのmoduleを消してzshを再起動して普段と変わりなく操作できるかを確認したりもした。

大概はまったく使っていないaliasが使えなくなる程度なので大して困らなさそうだという気持ちでゴリゴリ消していった。一つmoduleを減らすたびにだいたい100~200 msec ほど高速化していったのでこれはやりがいがあった。

最終的な結果は以下:

❯ for i in $(seq 1 10); do time zsh -i -c exit; done
zsh -i -c exit  0.79s user 0.40s system 108% cpu 1.100 total
zsh -i -c exit  0.78s user 0.39s system 108% cpu 1.070 total
zsh -i -c exit  0.77s user 0.39s system 108% cpu 1.069 total
zsh -i -c exit  0.79s user 0.39s system 109% cpu 1.083 total
zsh -i -c exit  0.78s user 0.38s system 108% cpu 1.065 total
zsh -i -c exit  0.80s user 0.40s system 108% cpu 1.099 total
zsh -i -c exit  0.79s user 0.40s system 109% cpu 1.090 total
zsh -i -c exit  0.80s user 0.40s system 107% cpu 1.110 total
zsh -i -c exit  0.79s user 0.40s system 108% cpu 1.100 total
zsh -i -c exit  0.80s user 0.40s system 108% cpu 1.100 total
num  calls                time                       self            name
-----------------------------------------------------------------------------------
 1)    1         363.84   363.84   54.43%    363.55   363.55   54.39%  __kubectl_bash_source
 2)    4         266.00    66.50   39.80%    135.32    33.83   20.24%  pmodload
 3)    1          73.05    73.05   10.93%     72.62    72.62   10.86%  _zsh_highlight_load_highlighters
 4)    2          27.63    13.82    4.13%     27.63    13.82    4.13%  compaudit
 5)    1          27.16    27.16    4.06%     27.16    27.16    4.06%  -zcache-hook-antigen
 6)    2          37.80    18.90    5.66%     10.17     5.08    1.52%  compinit
 7)    2           7.16     3.58    1.07%      7.16     3.58    1.07%  promptinit
 8)    1           7.06     7.06    1.06%      7.06     7.06    1.06%  _zsh_highlight_bind_widgets
 9)   14           6.48     0.46    0.97%      6.48     0.46    0.97%  (anon)
10)    1           3.63     3.63    0.54%      3.63     3.63    0.54%  async_init
11)   12           1.84     0.15    0.27%      1.84     0.15    0.27%  add-zsh-hook
12)    1           1.20     1.20    0.18%      1.20     1.20    0.18%  colors
13)    2           5.90     2.95    0.88%      1.06     0.53    0.16%  prompt_pure_setup
14)    3           0.90     0.30    0.13%      0.90     0.30    0.13%  is-at-least
15)    2           4.44     2.22    0.66%      0.81     0.40    0.12%  async
16)    1           0.30     0.30    0.05%      0.30     0.30    0.05%  -antigen-interactive-mode
17)    2           0.26     0.13    0.04%      0.26     0.13    0.04%  compdef
18)    1           6.68     6.68    1.00%      0.21     0.21    0.03%  set_prompt
19)    4           0.21     0.05    0.03%      0.21     0.05    0.03%  -set-default
20)    1           5.59     5.59    0.84%      0.19     0.19    0.03%  -antigen-env-setup
21)    1           0.29     0.29    0.04%      0.16     0.16    0.02%  complete
22)    1           0.20     0.20    0.03%      0.14     0.14    0.02%  -zcache-antigen
23)    2           0.25     0.13    0.04%      0.10     0.05    0.01%  -zcache-antigen-hook
24)    1          27.25    27.25    4.08%      0.09     0.09    0.01%  zcache-start
25)    1           6.73     6.73    1.01%      0.05     0.05    0.01%  prompt
26)    1           0.04     0.04    0.01%      0.04     0.04    0.01%  is-callable
27)    1           0.04     0.04    0.01%      0.04     0.04    0.01%  bashcompinit
28)    1           0.28     0.28    0.04%      0.03     0.03    0.00%  antigen
29)    1           0.06     0.06    0.01%      0.02     0.02    0.00%  antigen-bundle

次のボトルネック__kubectl_bash_source...なのだが、これはkubectlの補完を効かせるやつ (ここ)。最近はkubectlを触る機会があるのでこれを外すとそこそこ困るうえに代替案がパッと思いつかなかったので一旦放置。外すとようやく1秒未満で起動するようになるので補完機能も遅延で追加できたりしないかな。

環境

  • macOS 10.14.2
  • zsh 5.3 (x86_64-apple-darwin18.0)
  • prezto (versionの確認方法がわからないが、~/.antigen/repos/.zpreztoにcloneされたrepositoryのHEADはa338cba805f63f770e9078925bc5c46129e28bde)

JetBrains Free Open Source Licenseを取得した

JetBrains Free Open Source Licenseを取得したのでやったことをメモしておく。このライセンスは1年ごとに更新が必要なため、来年も同じ手順を行うかもしれない。

Free Open Source Licenseとは

Open source projectでの開発に使用できるライセンスのこと。利用するにはJetBrainsが定める条項を満たす必要がある。その条項は以下から確認できる。

www.jetbrains.com

注意点があって、取得したライセンスは非商用開発にしか利用できない。商用・業務で利用する場合は別途ライセンスを取得しなければならない。

  • Licenses can be used for non-commercial OS development only. Please consider purchasing separate licenses to work on commercial projects.
  • Use of the software is restricted to the licensed user with no right to transfer the software to any third parties.

取得方法

上記サイトに書いてあるので省略する。基本的には「自分がどのプロジェクトのcore contributorであるのか」を示す情報でフォームを埋めていくだけ。

自分は特定の著名OSSのcore contributorというわけではないので、自身で開発しているgoofiというweb applicationで申請を行った。

github.com

OSS contributionを支援するOSSという若干メタな立ち位置なうえ、99%一人で開発しているので Your OS project's community is active. という条件を満たさないかもしれないとは思っていたが通ってよかった。

goofiについては以前に発表した内容があるので詳細は以下。

Node学園祭 #nodefest で『貢献できるOSSの見つけ方 -完結編-』という発表をしてきました - valid,invalid

申請内容

f:id:ohbarye:20190427145701p:plain
申請時の入力フォーム

上記画像で見切れてしまっているProject description欄には以下の文章を書いた。

Goofi is a simple web application to list issues labeled as "good first issue" in major repositories. With this app, developers who would like to contribute to anything can find issues or repositories to contribute.

What this app tries to solve is "contribution barrier": In my observation, most OSS projects want more contribution and there are quite many developers who would like to contribute to any OSS project but most of them don't know how to find issues or repositories. Therefore, unfortunately, nothing happens. It seems there is a barrier.

Acceptされるまで

2019-03-28 22:47 JST に申請し、2019-04-01 21:04 JST にAcceptされたとのメールが来た。

その後

ふだんはRubyMineを使っているのでこの機会にまったく普段さわらないやつを使ってみたいと思う。とりあえずCLionでC言語を(初めて)書いてみている。

また、複数の製品を管理するためのJetBrains Toolboxという製品があると知ったので試しているがなんだか挙動が安定しない気がする。

JetBrains Toolbox App: Manage Your Tools with Ease

macOSでirbのhistoryが使えなくなったときの対処法

あるmacOSでいつの間にか、irbhistoryが使えなくなっていた。使えないとは、irbで矢印キーの↑を押すと制御文字 ^[[A が表示され、ENTERを押すとirbプロセスが終了するような状態。

$ irb
irb(main):001:0> RUBY_VERSION
=> "2.6.0"
irb(main):002:0> ^[[A

$ 

Ruby versionは異なるが、macos - IRB history not working with Ruby 2.3.0 - Stack Overflowに従って再インストール(再ビルド)することで解消した。

rbenv automatically detects homebrew and looks in it for readline, so, if you're using Homebrew and irb history doesn't work, you either haven't installed readline or you built your Ruby before you installed readline.

  • brew install readline if it isn't installed already
  • rbenv uninstall 2.3.0
  • rbenv install 2.3.0

なぜこれで直るのか?

StackOverflowの解説を読んでへーと思ったのでメモ。

OS X's command-line editing is based on the libedit library. OS X has a version of the readline library which is a wrapper around libedit, but it does not behave completely like GNU readline. irb history works in Ruby built with OS X's wrapper up to Ruby 2.1, but Ruby 2.2 and later need to be built with GNU readline for irb history to work.

  • OS Xコマンドライン編集ではlibeditのラッパーを使っているがGNU readlineとの完全な互換性はない
  • Ruby2.1まではそれで動いていたが、2.2以降はGNU readlineとともにビルドする必要がある
  • Rubyのビルド時にhomebrewでインストールされたreadlineを検出して使用するようになった ref

readlineとは?

以下の記事に詳しい。

readline は、CUI アプリケーションにおいてユーザが行を入力する際に便利な「行頭・行末移動」「ヒストリ機能」などを提供するライブラリである。readline というコマンドがあるわけではない。

readlineコマンドの使い方: UNIX/Linuxの部屋より引用)

そもそもlibeditとは?

知らなかったのでググった。

readline のライセンスが GPL であることを嫌い、NetBSD 界隈で readline 互換の libedit というライブラリが開発された。editline と表記することもある。

libedit は GPL ではなく BSD ライセンスとなっている。readline との互換性 100% が目標だが、libedit 独自の機能拡張もある。

readlineコマンドの使い方: UNIX/Linuxの部屋 より引用)

とのこと。ややこしい。

macOSのlibeditに関する問題点は他にもいろいろあるようだ。

環境

対人関係のリスクを取っている

今日職場で↑のツイートに言及して「ohbaryeさんは対人関係のリスクを取っているんですか?」と聞かれた。

どう見えますか?と質問を質問で返すと「取っていると思いますよ」とのこと。(なるほど?)

なぜリスクを取るか…いろんな思惑はあるが一つはやはり健康な職場を目指したい気持ちがある。この文脈でいう健康はハイコンテクストなのだが二段階あり:

  1. 対人関係のリスクを取れる状態(過渡期)
  2. リスクを取るのが常態化してきて、もはやリスクと感じない状態(理想形)

2を目指すためにはまず自分が率先してリスクを取っていき、それが当たり前な状態にしたいからリスクを取っていきましょう、という話をした。

俺が日和ってたら殴ってくれ!


余談だが、リスクを取っているが周囲にはそのように思わせないスキルを持っている人もいて凄みがある。

2018年に読んで心が動いた漫画 (1)

2019年1月も終わっていますが2018年に読んで心が動いた漫画の一覧を紹介します。対象は以下。

  • 2018年に買った・読んだ漫画
  • 2018年より前から読んでいて続刊を買った・読んだもの
  • 2018年以前に完結しているが初めて読んだもの

おすすめ順に並べるとかカテゴリ順に並べるとか考えたのですが終わらなさそうなのでやめました。コメント量が多いものがおすすめです(たぶん)。

また、一記事に収まらなかったのでとりあえず20作品だけ。

続きを読む

GatsbyjsがContributorにグッズを配布したりする取り組み

Static site generator の GatsbyJS が掲題の取り組みを始めたようす。


朝起きたらだいぶ前にめっちゃ小さくコントリビュートしたときの pull request にコメントが付いていた。

f:id:ohbarye:20190217181458p:plain

Gatsby community の OSS に貢献した人への感謝の気持ちとして

  1. Gatsby Swag Store*1 でグッズと引き換えられるクーポンをあげる
  2. GitHubGatsby organization に招待する

とのことだった。早速グッズを注文*2して org にも join してみた。

f:id:ohbarye:20190217182223p:plain
Tシャツと迷ったのだがテック系イベント等で入手したTシャツが棚に溢れているのを思い出してキャップを選択


sustainable な OSS community をどのように成立させるか?という問については昨年のNode festivalで発表する程度には関心があるので、この取り組みは非常に面白いと思った一方、グッズのデザイン・製造・販売、これはもはや事業だよな〜と思っていたら2018年5月にすでに会社が設立されていたことをいまさら知る。


興味が湧いた方はぜひ Contribution をどうぞ。

github.com

*1:Shopify製

*2:到着には 6 weeks or more かかるらしい