読者です 読者をやめる 読者になる 読者になる

「CoffeeScriptの関数は明示的にreturnしてはいけない理由」を探す暇あったら他にやるべきことあるのでは?

CoffeeScriptの関数は明示的にreturnするべき | CreativeStyle

本当に遅いのか、それを確かめましょう。

適当にでっちあげたコードです

f1 = ->
  for i in [1, 2, 3]
    for j in [4, 5, 6]
      i + j

f2 = ->
  for i in [1, 2, 3]
    for j in [4, 5, 6]
      i + j
  return 

console.time "f1"
for i in [1..100000] then f1()
console.timeEnd "f1"

console.time "f2"
for i in [1..100000] then f2()
console.timeEnd "f2"

実行してみます

$ coffee hoge.coffee 
f1: 105ms
f2: 4ms

約26倍違う、ということがわかります。 10万ループで100ms。1回ループあたり 1マイクロ秒の遅延があることがわかります。 1マイクロ秒、すごいですね。

1ループあたり1マイクロ秒の精度が要求されているか

このcoffeeで1マイクロ秒が要求されるケースがあるでしょうか。Nodeで秒間1万リクエストならありそうですね。 しかしこれはワーストケースに近い擬似コードです。おそらくこのループの中で、coffee-scriptによって生成された箇所のコストが、実際に記述するコードのコストを上回ることは考えにくいです。

そもそも制御フローを簡易に記述することを目的としてcoffee-scriptの採用、coffee-scriptの暗黙リターンがあります。これを理由に読みにくくできるコードが読みにくくなるならcoffee-scriptの採用に対して本末転倒です。

逆に言うと、「coffeeのfor, ifは値を返すことを前提に書くべき」で、長いロジックを書いてしまったせいで暗黙リターンが適用できなくなっているぐらいにコードが長くなっているとしたら、それが問題です。

早すぎる最適化

暗黙リターンの禁止よって書きづらくなるコードに以下の様なものがあります。

ids = users.map (u) -> u.id

もともとこういうコードですね

var ids = users.map(function(u){
  return u.id;
});

日頃高速なコードを書く必要があるなら明示的なリターンによるコストを気にする必要があるでしょう。そういう人間がJavaScriptを書いているとは考えにくいですけど。僕だったら部分的にasm.jsの採用を考えますが。

言語の基本機能や構文レベルでのコードの速度を気にすべきは、基本的にライブラリ実装者や高速な数値計算を目的にする人間だけです。そのコストも、アルゴリズムの改善で直接的に解決でき、そしておそらくは手元のネットワークIOやjQueryのクエリ一個のコストを大幅に下回るものでしょう

まとめ

「コードの速度が問題になるなら、その時はじめて最適化すべき」

コスト感がない人間に、「遅いらしいから」コードレビューでリジェクトされるような環境で仕事をしたくはありません。絶対に。

目の前に本当に遅いコードが転がってるだろうのに、こんなことばかり気にしてる人が多すぎます。div.innerHTML += s.toString() for i in [1..100] と書いてないか不安になります。

なんでこんな風に憤ってるかというと、こういう人や、こういう人を真に受ける人が上司になると、拡張for禁止になったりLINQ禁止になったりその他モダンな言語のモダンな機能の禁止をされて著しくモチベーションが落ちるからです。転職案件です。