0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

1秒ずつ削ったら、50秒が5秒になった ― オーパス先生の改修の話

0
Posted at

はじめに

前回の記事の最後に、こう書きました。焼く(アドインの更新登録)の待ちは、まだ測っていません。次に棚を直して焼くときに、内訳を測ります。

測りました。測ってみたら、前回の記事に書いた「約 20 秒」は、すでに縮み始めた後の数でした。その日の午前までは、焼くたびに 45 秒から 57 秒かかっていました。それが、いちばん速いときで 4.7 秒になっています。

私は昔から、マクロを作るときに 1 秒を削ることを考えてきました。毎日何十回も撃つマクロが 1 秒縮めば、積もり積もって何十分にもなる。プログラムを書くのは、そもそも時間を削るためです。

ところが、Excel を相手に AI と作ってきた道具そのものが、その 1 秒をずっと見落としていました。今回は、十月二十九日の夕方から三十日の明け方まで、番頭のオーパス先生(Claude Opus)と、手を動かすフラッシュ君(Gemini 3.8 Flash)が、道具の待ち時間を 1 秒ずつ削っていった話です。

TL;DR

  • 焼き(アドインの更新登録)は 45〜57 秒から、いちばん速いときで 4.7 秒になりました
  • 試験の全部は 35〜40 秒から 14 秒に、表を整える手(seiri)は 2.4 秒から 1.3 秒に、棚の問題集の判定は 7.65 秒から 1.85 秒になりました
  • マクロを一か所直す手は、本物の大きさのブックで 3〜4 秒から 0.25 秒になりました。一度は試しのブックの数で削れたつもりになり、この記事を書く途中で気づいて、その夜のうちにやり直した結果です
  • 秒は二週間前から道具の台帳に書いてありました。だれも数えていなかっただけです。いまは道具が遅い手を名指しします
  • 直し方は玉ねぎの皮むきでした。内訳を出して、いちばん重い段だけ削る。すると次の段が見える
  • 試験を減らしたら速くなりました。 守っているつもりの試験が、費用に見合っていませんでした
  • 縮めた所の多くは VBA と Excel をつなぐ道具の側です。ただ、VBA の側にも、高速化の定石どおりの直しが三つあります

遅さは台帳が知っていた

秀エクセルマネージャーは、AI と Excel の間に立つ道具です。AI が「このマクロを直して」「この表を整えて」と道具に頼み、道具が Excel に撃つ。その一回ごとに、道具は台帳に一行を書いています。何を撃ったか、どのブックか、通ったか、そして何秒かかったか。

この秒の欄は、二週間前からありました。ただ、だれも数えていませんでした。

番頭が使い捨ての台本で台帳を数えて、初めて見えたことがあります。十月十五日からの二週間で、マクロを一か所直す手(patch)は 874 回撃たれていて、一回あたりは真ん中の値で 3.3 秒、合わせて約 50 分でした。焼きは 376 回で、合わせて約 2 時間です。そのうち 88 回は、一回で 40 秒を超えていました。

1 回なら気になりません。でも回数を掛けると話が変わります。焼きが一回 40 秒縮めば、二週間で 4 時間近くになります。

AI は、1 秒を気にしない

このとき私は、番頭に、君とか AI はそんな 1 秒くらいの短縮はあまり気にしないからな、と言いました。

番頭の答えは、その通りです、でした。AI は待つ側にいないので、1 秒の差を体で感じない。だから、待ち時間を減らすより、機能を足す方に目が向く。焼きが毎回 45 秒かかっていても、気にしていなかったのが、その表れだと。

体で感じないなら、数字で気づくしかありません。そこで道具に stats --slow という手を足しました。台帳を数えて、遅い手を回数と合計の秒で並べ、道具の側から名指しします。番頭は、仕事の始めにこれを一回撃つことにしました。

数えた

1 秒の中身は、4 種類

記事を書きながら、私は一つ分からなくなりました。そもそも、なぜ 1 秒が削れるのか。番頭に聞くと、こういう答えでした。1 秒の中身のほとんどは、本当にやりたい仕事ではない。 中身は、だいたい 4 種類に分けられるそうです。

一つめは、往復の回数です。 道具(Python)と Excel は別々のプログラムで、セルを一つ読む、属性を一つ見る、という頼みのたびに、プログラムの間を行って帰ってきます。一回は 1000 分の 1 秒ほどでも、数百回、数千回と重なると秒になります。たとえば、フォームを書き出す手は、部品の属性を一つずつ 440 回読んでいます(ここはまだ削り残しです)。買い物でいえば、品物を一つ買うたびに家と店を往復している形です。メモにまとめて一回で買えば、買う物は同じでも時間はまるで違います。

二つめは、同じ仕事の二度撃ちです。 次の節に出てくる、マクロを一行直すたびに全モジュールを読み直していた話がこれです。表を整える手(seiri)も、表を整えるマクロが罫線と列幅をそろえた後に、仕上げでもう一度そろえていました。

三つめは、要らない仕事です。 焼く前の重い試験 25 本は、毎回何秒もかけて、ほとんど何も見つけていませんでした。回す試験が 0 本のときでも、試験用のブックの写しを作っていました。それだけで 8.9 秒です。

四つめは、一回ごとの固定の手間です。 seiri は、表の汚れに気づいたら棚のマクロを撃って直します。そのとき、棚を一本ずつ撃っていました。一本ごとに「Python から Excel に頼む」「表の範囲を探し直す」がかかります。三本を一回の頼みでまとめて撃つ形にしたら、1.10 秒が 0.16 秒になりました。中身の仕事は同じで、減ったのは呼び出しの手間だけです。

VBA の側の直しも、同じ理屈でした。問題集を判定するマクロは、同じ文字列を Split で切り直すのを 62 万回やっていました。一回切っておいて使い回せば、切るのは一回で済みます。

そして、どこを削ればいいかが分かるのは、番頭が速いコードを書くのが上手いからではない、とも言っていました。仕事を段に分けて、段ごとに時計を当てているだけだと。45 秒をひとかたまりで見ていると、どこが重いのか分かりません。

私が昔からマクロでやってきた、Select をやめる、画面の更新を止める、配列にまとめて書く。どれも、この 4 種類のどれかを削る手です。今回はそれを、Excel の外の道具の側でもやった、ということでした。

玉ねぎの皮むき

名指しされた中で、いちばん重かったのが焼きです。

焼くと言っているのは、開発用のブック(秀コンボ.xlsm)を、ふだん Excel に入れて使うアドイン(.xlam)に書き出して入れ直すことです。ただ書き出すだけではなく、その前に関所があります。棚のマクロが頼みの言葉に正しく当たるかの問題集と、試験を回して、一つでも落ちたら焼かない。

45 秒の中身が分からなければ、削りようがありません。そこで、焼くたびに道具が段ごとの秒を出すようにしました。内訳です。

内訳を見て、いちばん重い段だけを直す。直すと、次に重い段が見えてくる。また直す。玉ねぎの皮を一枚ずつむいていくような仕事でした。

焼きの秒 いちばん重かった段 直したこと
45〜57 試験の全部(約 35 秒) 重い試験 25 本を、ふだんの試験から外す(次の節)
17.7 確かめ用のブックの写し(8.9 秒) 回す試験が 0 本なら、写しを作らない
9.7 問題集の全問比べ(4.1 秒) 棚の頭の語が前と同じなら、全問比べを飛ばす
5.7 アドインの入れ直し(3.4 秒) 外して入れ直す代わりに、閉じて開き直す
4.7

35 秒の段があるうちは、3 秒の段にはだれも目を向けません。重い段の陰に、次の段が隠れているのです。焼くたびに道具が「いちばん長いのはこの段で何秒」と一行出すようにしたのが、いちばん効きました。

正直に書くと、4.7 秒はいちばん速いときの数です。直す中身によって、関わる試験の数が変わります。台帳を見ると、その後も、試験が多く関わる直しでは 10〜20 秒かかっています。それでも、毎回 45 秒以上だった頃とは別物です。

一行直すたびに、全部を読み直していた

マクロを一か所直す手(patch)の 3.5 秒も、内訳を見ると中身が分かりました。

マクロを一行直すたびに、道具はブックの全モジュールのコードを読み直していました。VBA は、変数名の大文字小文字をブック全体でそろえてしまうので、それを補正するためです。直すのは一行でも、読むのは全部。それが 3.5 秒の大半でした。

読んだコードを覚えておく形(キャッシュ)にしました。ただ、最初の形には穴がありました。覚えたコードが古くなったかを、ファイルの更新時刻で見分けていたのです。開いているブックに直接書いて、保存しないまま次の直しをすると、更新時刻は変わりません。古いコードを返してしまう。点検で見つかって、直しています。

速くする直しは、速くなったかどうかより先に、同じ答えを返しているかを見ないといけない。この夜、何度も出てきた話です。

そして、もう一つ正直に書いておくことがあります。この直しの後、試しのブックでは patch が 0.3〜1.0 秒になり、番頭はそれで「1 秒以内」と報告していました。ところが記事を書くために台帳を見直すと、モジュールの多い本物のブック(秀コンボ)では、その後も 3〜5 秒かかっていました。小さい土俵で測って、削れたつもりになっていたのです。フラッシュ君の報告で何度も直させてきた型を、番頭が自分でやっていました。

そこで、その夜のうちにやり直しました。今度は、秀コンボを写した同じ大きさのブックで測ります。内訳を出すと、全モジュールの読み込みと補正は 0.8 秒から 0.01 秒まで削れました。残ったのは、直すたびにブックを保存する 1.5 秒です。これは Excel 自身の保存で、道具の側からは削れません。

保存をやめれば速くなります。ただ、Excel が落ちたらマクロの直しが消えます。私は、保存は残して、返事を先に返し、保存はその後ろで回す形を選びました。AI が返事を読んで次の手を考えている間に、保存は終わっています。待ち時間から 1.5 秒が消えて、返事までは 0.25 秒になりました。

この直しの確かめで、もう一つ穴が出てきました。読み取り専用で開いたブックでも、道具は「保存した」と答えていたのです。確認の窓を切った Excel は、読み取り専用のブックの保存を、黙って何もしないことがあります。今は、保存の前に読み取り専用かを見て、保存の後にまだ未保存なら、失敗として返します。速くする直しは、やはり同じ答えを返しているかを見ないといけません。

皮をむく

試験を減らしたら速くなった

焼きの前の関所には、135 本の試験がありました。番頭は、速くするための直しの指示書に、「試験は減らさない」という縛りを書いていました。

私は、その約束は捨てろ、と言いました。目的は速くすることです。それに、あの重い試験が実際に穴を見つけたのは、これまでにせいぜい三回くらいだったはずだ、と。

数えてみると、本当に効いていた守りは、軽い方でした。問題集の全問比べと、コンパイルと、実機で撃って比べること。重い試験の中には、毎回何秒もかけて、ほとんど何も見つけていない物がありました。

重い 25 本は、ふだんの試験から外して test --slow に回し、まとめて確かめたいときだけ撃つ形にしました。試験の全部は 35〜40 秒から 14 秒になり、焼きも 45〜57 秒から 17.7 秒に落ちました。皮むきの一枚目は、この話です。

守りを足すのは簡単です。足した守りが、かけている時間に見合っているかを数えるのは、足すより難しい。番頭は「減らさない」と書くことで、それを数えずに済ませていました。

VBA の側の三つ

ここまで書いたのは、ほとんどが道具の側の話です。Python から Excel に何回往復するか、焼く前に何を確かめるか、試験をどう回すか。「VBA で速くした」と読まれると、正確ではありません。

ただ、VBA の側にも直しが三つありました。マクロを書く人には、ここがいちばん身近な所だと思います。

一つめ:問題集の判定を 7.65 秒から 1.85 秒に

棚のマクロが頼みの言葉に正しく当たるかを、1,557 問の問題集で判定するマクロです。番頭が指示書を書き、フラッシュ君が直しました。直したことは、VBA の高速化の定石そのものでした。

  • 棚の目録を読むのは一回だけにして、Static で覚えておく
  • 62 万回撃っていた Split を、前もって分けておいた配列に置き換える
  • 文字列を & でつないでいくのをやめて、配列に入れて最後に Join する
  • 頼みの文の長さで、InStr を撃つ前に見込みの無い組み合わせを弾く

どれも、私が自分のマクロで 1 秒を削るときにやってきたことです。AI が書いたマクロでも、遅い所は同じ所にありました。

二つめ:アドインの書き出しを 3.7 秒から 1.7 秒前後に

焼きの最後の段、アドインを書き出して入れ直すマクロです。これもフラッシュ君が、指示書を三本受けて直しました。

  • 写しを開き直さずに、SaveCopyAs で直接書き出す
  • アドインを外して入れ直す代わりに、閉じて開き直す
  • 開く間は再計算を手動にして、終わったら元に戻す。失敗して途中で抜けた道でも元に戻す

三つめ:2 秒の暗転を一瞬に

焼くたびに、Excel の画面が 2 秒ほど暗くなっていました。私が気づいて言うと、番頭は最初、窓の描き直しを止める手で直そうとして、外しました。当て推量でした。

そこで番頭は、焼いている間の画面の明るさを 0.1 秒おきに記録しました。暗い 2 秒が、アドインを書き出す段とぴったり重なっています。原因は順番でした。画面の更新を止めてから、窓を隠していた。止めるのを、隠した窓を戻した後に回すと、2 秒の暗転は一瞬のちらつきになりました。

Excel は、アドインとして保存することを、ブックをアドイン扱いに切り替える形でしか許していません。切り替えると窓は必ず隠れるので、一瞬のちらつきまでは消せません。それでも、2 秒暗くなるのと一瞬とでは、使う側の感じ方がまるで違います。

これも、測ってから直した方が早かった例です。

一瞬だ

フラッシュ君との分担

この一晩のやり方そのものも、書いておきます。

番頭のオーパス先生は、Excel を自分では撃ちません。台帳を数え、指示書を書き、上がってきた報告を点検するだけです。手を動かすのは、Antigravity で動いているフラッシュ君です。

からくりポケット

番頭は、決まったフォルダに、番号付きの指示書を置きます。フラッシュ君は、まだ報告の無い指示書を番号の小さい順に拾ってやり、報告を書き、指示書が無くなったら止まります。私はこの仕組みを、からくりポケットと呼んでいます。

指示書の形は決まっています。なぜ(台帳の数字)、直してよい所、やること、合格の条件、報告の形。いちばん効いたのは、合格の条件を数字で書くことでした。「速くして」とだけ書くと、少し速くなった所で「完了」と返ってきます。「1.3 秒以内」と書くと、届くまで続けます。表を整える手(seiri)の指示書には「直す所のある表で 1.3 秒以内」と書き、2.41 秒が 1.29 秒になって返ってきました。

点検から、次の仕事が生まれる

番頭は、報告の数字を台帳で数え直し、説明をコードの行と突き合わせます。穴があれば、その場で「〜の 2」として直しの指示書を置きます。

これが、長い時間続けられる理由でした。点検するたびに次の仕事が生まれるので、仕事が途切れません。二十九日の夕方から三十日の一時までに、報告は 27 本上がってきました。一本あたり 5 分から 1 時間です。

育てる

報告には、同じ形の誤りが何度か出てきました。目当てに届いていないのに合格と書く。小さい表で測って速いと言う。測るために入れた跡を戻し忘れる。

そういう型が見つかるたびに、番頭はフラッシュ君の決まりの紙に一行足しました。次の報告から、その型は出なくなります。報告の頭には、指示に無いことを足していないか、などの四つの欄を、最後には自分で何を確かめたかを書く決まりにしています。

Excel が古いから遅い、のではなかった

この夜の作業の合間に、新しい表計算ソフト(ibisOffice)の紹介動画を見ました。それを見て、やっぱり Excel は古い作りなんだな、と思いました。

ただ、この夜に削った秒を並べてみると、Excel そのもののせいだと言えるのは、アドインを開き直す 1.5 秒と、ブックを保存する 1.5 秒くらいでした。残りは、一行直すたびに全部を読み直す、要らない試験を回す、同じ仕事を二度撃つ、写しを作る。遅さの多くは、Excel の使い方の側にありました。

減らしたのは、ほとんどが Excel との往復の回数です。公開しているこの道具を落として使う人の PC が、私の PC より速いとは限りません。往復一回あたりの時間が長い PC ほど、回数を減らした効き目は大きくなります。

真似するなら

ここまで、私の机の上の話を書いてきました。ただ、やったこと自体は特別な腕ではありません。AI に頼めば、だれの机の上でも同じことができます。自分のマクロで試すなら、手は三つです。

一つめ、秒を記録する。 まず、待っている時間を数字にします。VBA なら、Timer で段ごとの秒を出す行を足すだけです。

Dim t As Double: t = Timer
' …読み込み…
Debug.Print "読み込み", Format(Timer - t, "0.00"): t = Timer
' …計算…
Debug.Print "計算", Format(Timer - t, "0.00"): t = Timer
' …書き出し…
Debug.Print "書き出し", Format(Timer - t, "0.00")

自分で書かなくても、AI に「このマクロに、段ごとの秒を出す行を足して」と頼めば足してくれます。

二つめ、いちばん重い段だけを見る。 出てきた秒を AI に見せて、「いちばん重い段で、何が起きているか」を聞きます。たいていは、さっきの 4 種類(往復の回数・二度撃ち・要らない仕事・一回ごとの手間)のどれかです。全部を一度に直そうとしないことが大事です。重い段の陰に、次の段が隠れています。

三つめ、削ったら、同じ答えかを確かめる。 速くなったかより先に、結果が前と同じかを見ます。表の写しを取っておいて、直す前と後のマクロの結果を比べる。これも AI に「前と後で結果が同じか確かめる手順を作って」と頼めます。

一つだけ、人の側にしかできないことがあります。待つのは人だけだということです。AI は待たないので、こちらから「何秒かかった?」「内訳は?」と聞かない限り、秒の話は始まりません。

事実と見立ての仕分け

事実。 秒は、道具が呼び出しごとに書いている台帳の実測です。焼きの 45〜57 秒と 4.7 秒は、番頭が台帳の行を数え直しました。表を整える手の 2.41 秒と 1.29 秒は、フラッシュ君の報告を番頭が点検したものです。直しはすべて公開リポジトリに入っています。

見立て。 AI と作る道具は、放っておくと遅くなる方へ育つ、と私は見ています。AI は待たないので、機能を足すことには熱心でも、秒を削ることには目が向きません。秒を削る仕事は、AI ができないのではなく、AI が気づかない。だから気づく役は、数字と人が持つしかありません。

正直な線引き

  • 5 秒は、いちばん速いときの数です。 関わる試験の多い直しでは、今も 10〜20 秒かかります
  • マクロを直す手の 0.25 秒は、返事までの秒です。 保存の 1.5 秒は消えたのではなく、返事の後ろに回しただけです。間を置かずに続けて直すと、前の保存の残りを待ちます
  • 縮めた所の多くは、道具の側です。 VBA の直しは三つです
  • 速さを取りにいって、やりすぎた所があります。 試験を CPU の数に合わせて最大 20 本同時に回す形にしたら、この PC でもメモリが足りずに試験が落ちました。力の無い PC だったら全部落ちる、と私が止めました。今は同時に回す数を、CPU の数と空いているメモリの小さい方で決めています。それでも、時間は 7 秒が 8.5 秒になっただけでした。なお、同時に回すのは私の机の上の同期と公開の確かめだけで、公開している道具には入っていません
  • 開発中です。 秒は、直すたびに変わります
  • Windows 版の Excel の話です

おわりに

1 秒を削るのは、地味な仕事です。1 回なら、だれも気にしません。

でも、毎日何十回も撃つ手なら、1 秒は回数の分だけ積もっていきます。その積もった時間を返してもらうのが、私にとってのプログラムでした。今回は、それを AI と一緒にやれた一晩でした。

焼くたびに 45 秒、黙って待っていたのは、私だけでした。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?