見出し画像

【ソフトウェア開発】性能はアーキテクチャの設計で作りこまれる

IT業界の中で一般的に使われる「性能」「非機能」と言うと、とかく機能やプログラムの「処理速度」「レスポンスタイム」ばかり気にしてしまいますが、実際には性能は非機能のごくごく一部でしかありません。

画像1

とはいえ、利用者にとってはほかの非機能に比べるとややプライオリティが高いのも事実です。なにせ、「遅い=イラっとくる」はユーザーにとって他人事ではない、切っても切れない関係にありますから。
 
では、性能面を考慮するにあたって、まずどこに着目するか?

と言ったとき、大抵エンジニアのみなさんは「情報リソースへのアクセス」部分に着目することでしょう。

 データベースがあるなら、DBアクセス
 ファイル操作があるなら、ファイルアクセス
 通信があるなら、通信アクセス
 他システムとの連携があるなら、他システムアクセス
 制御機器があるなら、機器アクセス     etc.…

もちろん、これらの考え方は間違ってはいません。
確かにボトルネックとなりやすい部分ではあります。

特にデータベースは、接続(open/close)でもそれなりに時間がかかりますが、その後のSQL文の実行も大きな障害となることはままあります。

たとえば、

「索引(index)を設定しているにも関わらず、SQLの実行速度が遅い」
「ヒント句を記述しているにも関わらず、索引が使用された形跡がない」

と言うことを経験した方もいらっしゃるかもしれません。この手の経験をされた方は、SQLをなんとなく利用してはいても、オプティマイザ(操作の最適化を行ってくれるDBの頭脳ともいうべき機能)の性質や、カーディナリティ(データの分布、濃度)をご存じなかったのかもしれませんね。


それら「情報リソースへのアクセス」への観点もたしかに重要ですが、ソフトウェアエンジニアとして、それ以上に見落としている部分があります。それは、コンピューターが1つの動作をするために、いったいどれだけのプログラムを読み取り、実行しているのかと言う、

 プログラムの実行量(行数)

です。

つまるところ、人間が作業するのと同じで、すべては「行動」の順序やその手続き量によって、すべてが決定します。コンピューターがプログラムを実行する量が多ければ多いほど、性能は劣化します(人間の場合、実際に身体(含 頭脳)を動かす作業量が多ければ多いほど、時間がかかるのと同じ)。

これは性能面において、最も注意しておくべき本質であり、また、至極当然な基本中の基本です。このことを失念していては、性能向上は図れません(人間の行動でいうと、「生産性が向上しません」)。

先の例でいうと、

「なぜデータベースに対するフルアクセスは遅いのか?」
    ↓
テーブルに格納されているデータを1件1件チェックしながら操作しているから。プログラムでいえば、繰り返し文で、全件走査しているのと同じ。

ファイル操作の例でいうと、

「なぜファイルアクセスは遅いのか?」
    ↓
ファイルのopen/closeもさることながら、行ごとやサイズごとに繰り返し操作しているから。

結局、処理が早いか遅いかは、プログラムの作成規模ではなく、プログラムが実行される行の規模によって起こるのです。10kstep(1万行)作っても、10step(10行)しか実行されなければ、性能的には10行の処理スピードになるので、問題は無いんです。逆に、1kstep(1000行)作って、100step(100行)実行されているのであれば、10kstep作ったプログラムよりも、処理スピードが遅くなるのは自明です。

特に、forやwhileなどの繰り返し制御文は、機能的には非常に便利ですが、性能を劣化させる原因にしかなりません。たとえば

x=0;
for(i=0; i<100; i++) {   // iの値が0から始まり、1ずつ加算。100になるまでの間、繰り返す
 x = x+1;
}

と書くと、作成行はたったの3行で、ものすごく効率的に見えますが、実際に実行される行数は

 (1回目)
   ①xに0を代入する
   ②iに0を代入する
   ③xに、(元のxの値+1)の計算結果を代入する
 (2回目以降)
   ④iが100未満の場合、iに1を加算する
   ⑤xに、(元のxの値+1)の計算結果を代入する
 (100回目)
   〇iが100になっているため、{}ブロックに入らず、終了する

この間、実に190回以上のプログラム行が実行されていることになります。

こうした特性を考慮したうえで、極力繰り返さなくてもいい"設計思想"というものを、普段から考えたことはあるでしょうか。

元来、性能要件と言うのは、要件定義の時点である程度決まっています。たとえば、業務システムなどの場合は

 「ある画面から次の画面へ遷移する際に要する時間は3秒」
   ・"遷移"とは、次の画面の情報がすべて表示された状態までを指す

なんてのがありますね。通称「3秒ルール」とも言われています。当然、遅くても3秒以内…ということなので、どれもこれも3秒かかっていたら怒られます。あくまで「我慢できるのが」3秒まで、というだけです。

言ってみれば、私たちIT企業に発注していただいた時点で、お客さまの頭の片隅には「一般的な常識の範囲内で」性能を求めています。ゆえに、私たちは

画像2

と言った流れで、ITシステムの性能品質に対し、開発ライフサイクル全体を通して作り込まなくてはなりません。

性能品質を作り込んでいくには、開発工程の早い段階からその工程に応じた対策を打っていくことが必要です。つまり、終盤のテスト工程になって初めて性能をチェックするのではなく、「実装までに性能を見極めておき、性能テストで想定の性能に収まっていることを確認するだけ」という姿勢で臨むべきなのです。でなければ、最後の最後になって1から作り直し…と言うことにもなりかねません。

たとえば、Webシステムの例でいうと、以下のようなイメージを持っていなければ、局所的な対応しか思いつきもしません。

サーバー処理時間 = ①静的コンテンツ処理時間
         + ②APサーバープロセス処理時間
         + ③業務ロジック処理時間
        (+ ④-1 DBサーバー接続時間)
         + ④-2 SQL文解析時間
         + ⑤-1 ディスクI/O
        (+ ⑤-2 DBサーバー切断時間)

画像3

画像4

静的コンテンツというのは、スクリプトやCSS、画像など素材そのものです。これらはブラウザがHTMLを読み込んでから改めてダウンロードされるものですので、そういった素材を多用すればするほど、すべてを表示するまでの処理は遅くなっていくわけです。

いただいたサポートは、全額本noteへの執筆…記載活動、およびそのための情報収集活動に使わせていただきます。