可読性とパフォーマンスは別物なんだなと感じたこと

自分で書いたコードは何年も残る可能性があります。

他の人もしくは自分がもう一度コードを読んだときに、

それが読みやすいコードであれば嬉しいですね。

今回はパフォーマンスという切り口で可読性について考えてみます。

まずはこの記事での結論です。

  • パフォーマンスが高い/低いということは読みやすさではなく構造でわかる
  • パフォーマンス優先のコードにはコメントが効果的
  • パフォーマンスを出すのにインフラの力を借りることで可読性を維持する

パフォーマンスが高いということをコード上表現できなかった経験

私は仕事の関係上、負荷対策やパフォーマンス改善といった機会がありました。

パフォーマンスを追求するためにどのようなコードを書くかを考えるのですが、

この時に可読性から頭が離れることが多いです。

パフォーマンスが非機能的で可読性は機能的により近いとか

文章にするとお堅い感じになりますが、

要はコード中に「すごく早い」と書けなかったのです。

なぜ書けなかったのかをhello worldで紹介しようと思います。

どんな言語を使おうともhello worldプログラムをエンジニアならば一度は目にしたことはあるのではないでしょうか。

Console.Write("Hello");

なんてシンプル。

可読性とはHowやWhatを適切に表現できていれば上がると考えています。

その最たるものはhello worldですね。

「コンソールにHelloを出力する」はまさにWhatを表現していると思います。

では「コンソールにHelloを3回出力する」をいかに早くおこなうかというパフォーマンスに関する要求があったとします。

パフォーマンスを上げるということを表現するにはどんなコードがよいでしょうか。

試しに二つのサンプルをお見せします。

Console.Write("Hello");
Console.Write("Hello");
Console.Write("Hello");
for(int i = 0 ; i < 3; i++)
{
    Console.Write("Hello");
}

パフォーマンスを求めるときどちらのコードが早いでしょうか。

いったん答えは置いておきますが、

基準にするとしたならば、

「構造上早いか」やメモリなど言語性能やハードウェアの知識をもとに選択します。

ですが御覧の通りコード中に「早い」とは書けなかったのです。

これがパフォーマンスと可読性がぶつっと分かれていると感じた経験になります。

パフォーマンス追求と可読性は競合する

また可読性が低いほうがパフォーマンスを上げやすいことも多々あります。

というよりパフォーマンスと可読性が競合する場面のほうが多かったです。

パフォーマンスを上げるときの打ち手としては

  • 無駄なインスタンスはないだろうか
  • 無駄なループはないだろうか
  • 一度のループ処理に統合できないだろうか
  • etc.

「一度のループ処理に統合できないだろうか」などは特に可読性と競合しました。

複数のループ処理を一つに統合すると

本来であれば逐次的に読めていたコードが分断されるため、

当然読みづらくなります。

パフォーマンス追求時にコメント必須

クラスを使用していた部分をメモリ消費を抑えるために

クラス利用しないなどの策をとることもあります。

するとほかのメソッドではクラスを使用しているのに、

なぜかパフォーマンス出したいクラスには使用していない状況ができます。

そういう時は「パフォーマンスのため」とわかるようにコメントを入れておくとよいです。

でないと「他と統一しないと保守性下がるでしょ!」と修正されてしまい、

ある時「なんだか遅いんだけど・・・」みたいなことになります。

パフォーマンスはハードウェア性能でも向上する

パフォーマンスが求められる場面においても比重を考えて、

可読性がある程度のこるようにしたいものです。

パフォーマンスはハードウェア性能でも向上する。

この当たり前なことも積極的に使います。

可読性が落ちすぎると保守性も下がるという懸念もあります。

そこはトレードオフなのである程度のパフォーマンスは

ハードウェアで担保するという手をあらかじめ想定しておきます。

まとめ

パフォーマンスが求められる場面でも可読性を意識していきたいものです。

以下まとめです。

  • パフォーマンスが高い/低いということは読みやすさではなく構造でわかる
  • パフォーマンス優先のコードにはコメントが効果的
  • パフォーマンスを出すのにインフラの力を借りることで可読性を維持する