仕事に効くコンピュータサイエンス
待ち時間を設計する — I/Oと非同期読了目安 10分

待ち時間を設計する — I/Oと非同期

週次報告を作っているとします。自分の担当分はすでに書き終えました。あとは経理システムから先月の数字を取り込むだけです。ボタンを押すと、画面が固まったように動かなくなります。数字が返ってくるまで、あなたはただ待っています。この「待つ時間」は、なぜこんなに手持ち無沙汰なのでしょうか。

コンピュータの世界にも、まったく同じ問題があります。プログラムが計算をしている時間と、外部とのやり取りを待っている時間は、性質がまったく違います。この違いを区別し、待ち時間をどう扱うかを設計することは、コンピュータサイエンスの中でも古くから重要な主題として扱われてきました。本章では、この「待ち時間の設計」を4つの角度から見ていきます。

計算する時間と、待つ時間

まず区別すべきは、「自分の手が動いている時間」と「相手の返事を待っている時間」です。前者は資料を作る、数字を計算する、文章を書くといった、自分の中で完結する作業です。後者は、メールの返信、承認、外部システムからのデータ取得のように、自分以外の誰か・何かに依存する作業です。

コンピュータでは、前者を担うのがCPU(中央演算処理装置。計算そのものを実行する部品)で、後者を担うのが入出力、略してI/O(アイオー)です。ディスクからファイルを読む、ネットワーク越しに別のサーバーへ問い合わせる、キーボード入力を受け取る。これらはすべてI/Oです。I/Oは、CPUの計算に比べて桁違いに遅いという性質を持っています。ディスクやネットワークという物理的な部品が間に入る以上、電気信号や光が物理的に移動する時間、相手側の処理を待つ時間が必ず発生するからです。

仕事に置き換えると、CPUの計算にあたるのは「自分の頭と手だけで進む作業」です。資料の体裁を整える、文章を推敲する、数字を並べ替える。これらは他人の返事を待つ必要がありません。一方、I/Oにあたるのは「誰かや何かの応答を待たないと先に進めない作業」です。上司の承認、他部署からの回答、外部システムのレスポンス。これらは、自分がどれだけ急いでも、相手側のペースに縛られます。

問い合わせ対応の場面を考えてみます。顧客から届いた質問に答えるには、まず社内の別部署に事実確認をしなければならないことがあります。確認メールを送った時点から、返事が届くまでの時間は、あなたが手を尽くしても縮まらない「待ち時間」です。これに対して、届いた回答を顧客向けの文面にまとめる作業は、あなた一人の手の中で完結します。同じ「問い合わせ対応」という1つの業務の中にも、性質の違う2種類の時間が混ざっているのです。

なぜこの区別が仕事に効くのか

この区別が重要なのは、「待っている間、何もできない」状態と「待っている間も、他の作業を進められる」状態では、同じ8時間労働でも生み出せる成果がまったく違うからです。承認待ちのメールを開いたまま画面の前でぼんやりと待つのと、承認待ちの間に別の資料を進めるのとでは、1日の終わりの成果物の量が変わります。これは根性の問題ではなく、時間の使い方の設計の問題です。

コンピュータの設計者たちは、この事実に早くから気づいていました。CPUは非常に高価で貴重な資源でした。I/Oを待っている間、CPUを遊ばせておくのは大きな損失です。そこでOS(オペレーティングシステム。コンピュータ全体の資源を管理する基盤ソフト)は、あるプログラムがI/Oを待っている間に、別のプログラムにCPUを使わせるという仕組みを発展させてきました。1章で見たプロセス(実行中のプログラムのまとまり)やコンテキストスイッチ(実行する作業を切り替える処理)の考え方は、まさにこの「待ち時間に別の仕事を差し込む」ための土台でした。

仕事の現場でも、発想はまったく同じです。承認待ち、返信待ち、外部データ待ちという、いわば「I/Oが主役の時間」を、ただ突っ立って待つ時間にするか、その間に別の作業を差し込む時間にするか。この差を意識的に設計している人と、していない人とでは、1週間、1か月というスパンで見たときの生産量に大きな差が生まれます。会議調整でも同じことが起きます。日程候補を関係者に送り、全員の返信が揃うまでの数日間を、ただカレンダーを眺めて待つのか、その間に別の準備を進めるのかで、1週間の使い方は大きく変わります。

急いでも縮まらない時間

ここで注意したいのは、I/Oの遅さは、当事者がどれだけ手を尽くしても基本的に縮まらないという性質です。ディスクの回転速度やネットワークの物理的な距離は、プログラムの書き方をどれだけ工夫しても変えられません。CPUの計算は、アルゴリズムを見直せば速くなる余地がありますが、相手側の応答時間は自分の手の届かないところにあります。

これは仕事でも同じです。他部署からの回答、取引先の承認、システムのバッチ処理の完了。これらにかかる時間は、あなたがどれだけ丁寧に催促しても、相手の都合や仕組みの制約によって決まっています。もちろん催促によって多少早まることはありますが、根本的な処理時間そのものを消し去ることはできません。ここに時間と注意を割き続けるのは、CPUを高速化する工夫を、ネットワークの遅さに向けているようなもので、ずれた場所に力を入れていることになります。

この前提に立つと、時間の使い方に対する態度が変わります。「待ち時間をゼロにする」ことを目指すのではなく、「待ち時間の間、他に何ができるか」を目指すという発想の転換です。これは後のページで見るブロッキング・ノンブロッキングの話に直結します。

たとえば、外部の取引先からの見積回答を待っているとします。催促の電話を1本入れることはできても、相手の社内稟議の速度そのものを変えることはできません。ここで焦って何度も電話をかけ続けても、待ち時間は縮まらず、むしろ相手との関係を損ねるだけに終わることもあります。縮められない時間には、縮めることにこだわるのではなく、別の使い方を考えることに意識を向けるべきだ、というのがこの区別の実務的な帰結です。

見えにくい待ち時間ほど厄介

厄介なのは、待ち時間が目に見えにくい形で紛れ込んでいる場合です。画面が固まって動かなくなるような分かりやすい待ち時間なら、誰でもすぐに気づきます。しかし、たとえば「他部署からの回答をSlackで待っている状態のまま、通知が来たことにも気づかず1時間が過ぎていた」というような待ち時間は、本人にも自覚されないまま失われていきます。

引き継ぎ業務でも同じことが起きます。前任者に確認したい点をまとめて質問を送ったあと、返事が来るまでの間、次に何をすべきかが決まっていなければ、手が止まったまま時間だけが過ぎていきます。逆に、質問を送ると同時に「返事が来るまでの間に進めておける作業」をあらかじめ用意しておけば、同じ待ち時間でも中身はまったく違うものになります。

大切なのは、待ち時間そのものを悪者にすることではありません。待ち時間があること自体は避けられない前提であり、問題はその時間に何が起きているかが自分で見えているかどうかです。見えていれば設計できますが、見えていなければ、ただ時間が漏れていくだけになります。

本章で見ていく4つの視点

本章では、この「待ち時間の設計」を次の4つの視点から掘り下げます。

第一に、そもそも自分の作業が「頭を使う作業(計算が主役)」なのか「誰かの返事を待つ作業(I/Oが主役)」なのかを見分ける視点です。これが分からなければ、どこに待ち時間があるのかも見えません。次のページで扱います。

第二に、依頼を出したあと、返事が来るまでその場に張り付いて待つのか、それとも依頼だけ先に出して他の作業に移るのかという選び方です。これをコンピュータの世界では、処理を止めて待つ「ブロッキング」と、止めずに先へ進む「ノンブロッキング」と呼びます。

第三に、返事が来たかどうかを自分から何度も確認しに行くのか、それとも相手から知らせてもらう仕組みを作るのかという違いです。これは、こちらから見に行く「ポーリング」と、相手から知らせてもらう「割り込み」という対比で語られます。

第四に、複数の作業が連なっている場合、待ち時間そのものを重ねてしまう「パイプライン化」という発想です。1つの作業が終わってから次を始めるのではなく、待っている間に次の作業の準備を進める仕組みです。引き継ぎの多い業務ほど、この発想の有無で全体のスループット(単位時間あたりにこなせる仕事の量)が変わってきます。

これら4つは、それぞれ独立した技術用語のように見えますが、根っこにある問いは1つです。「待たされている間、自分は何をしているか」。この問いに自覚的になることが、本章のゴールです。

この視点を持つとどう変わるか

たとえば、1日のスケジュールを組むときに「これは自分の作業だけで完結するタスクか、それとも誰かの返事待ちが発生するタスクか」を色分けするだけでも、見え方は変わります。返事待ちのタスクは、依頼を早めに出しておいて、待っている間に別の作業を進める。自分だけで完結するタスクは、まとまった集中時間を確保して一気に片付ける。この仕分けができるようになるだけで、1日の中の手持ち無沙汰な待ち時間は目に見えて減っていきます。

コンピュータの世界でこの設計を突き詰めた結果生まれたのが、非同期(ひとつの作業の完了を待たずに、並行して他の作業を進める考え方)という仕組みです。非同期という言葉は難しく聞こえますが、中身は「依頼を出したら、返事を待つ間は他のことをする」という、誰もが日常でやっている工夫と同じです。違いは、それを偶然の工夫としてやるか、あらかじめ設計として組み込んでおくかにあります。

週次報告の例に戻ります。経理システムからの数字取得を待つ間、あなたにできることはいくつもあります。報告書の他の項目を先に埋めておく、来週の会議の準備を進める、たまっていた問い合わせに手をつける。どれを選ぶかは状況次第ですが、大事なのは「待っている間は何もできない」と思い込まないことです。この思い込みこそが、待ち時間を単なる浪費に変えてしまう最大の原因です。

反対に、待ち時間の間に手をつけた作業に深く入り込みすぎて、肝心の返事が来たことに気づかない、という失敗もよくあります。これは後のページで扱う「確認しに行くか、知らせてもらうか」という論点そのものです。待ち時間の使い方には、良い設計と悪い設計があり、その差を分けるのが本章で見ていく4つの視点です。

次のページからは、この「頭を使う作業」と「誰かを待つ作業」の見分け方から具体的に見ていきます。

持ち帰り

  • 作業には「自分の手だけで進む時間」と「誰かの返事を待つ時間」の2種類があり、性質がまったく違う
  • 待ち時間そのものをなくすことはできないが、待ち時間の使い方は設計できる
  • 本章は、区別する・依頼の出し方・確認の仕方・重ね方という4つの視点で待ち時間の設計を扱う

やってみる

明日の作業リストを見直し、それぞれのタスクに「自分完結」か「誰か待ち」かの印を1つずつ付けてみてください。印を付けるだけで、待ち時間がどこに隠れているかが見えてきます。