エンジニアHubPowered by エン転職

若手Webエンジニアのための情報メディア

ソフトウェアが持つべき機能と仕事の粒度を見極める〜The Platinum Searcherの作者に聞いてみた

GitHubでスター数2,000以上を獲得したOSSである「The Platinum Searcher」。作者の三宅悠介さんに、シンプルでありつつも、高い性能を持つソフトウェアを作り出すための思考を聞きました。

一つのことを、うまくやれ──。
ソフトウェア開発の規範として、多くのエンジニアに影響を与えたUNIX哲学には、こうした言葉があります。事実、過去お話を伺ったOSS開発者たちも、この言葉の重要性を口にしてきました。非常にシンプルな言葉にも感じますが同時にある疑問も浮かびます。ソフトウェア開発において、どのように「一つのこと」を定義し、どのように「うまくやる」をイメージするのか、と。

  • find:ファイルを検索する
  • grep:文字列を検索する
  • print:検索結果を表示する

パターン検索ツールである「The Platinum Searcher」が持つ機能は、原則としてこの3つのみです。UNIX哲学を踏襲したかのような、極めてシンプルなOSSのツールですが、その利便性と検索速度によって、スター数2,000を超える人気のOSSとなりました。

では、作者の三宅悠介(みやけ・ゆうすけ/ @monochromeganeさんは、どのように「The Platinum Searcher」の機能と果たすべき仕事を定義したのでしょうか。コードを書くその前にある、開発のための思考設計を聞きました。

解決したい課題はどこにある?

──ペパボ研究所という、極めてテクニカルな環境でお仕事をされていますが、大学は意外にも文系だったそうですね。

三宅 大学では環境施策を研究していたのですが、段々と興味がなくなっていってしまって(笑)。ただ、施策を考えるうちに、なにかを作ることによって、問題が解決する……例えば、ペットボトルがなにか環境に影響を与えているとしたら、ペットボトルの処理方法を考える、というわけではなく、ペットボトルそのものを変えてしまえばいい、といった考え方に変わっていったんです。“モノ”を変えることで世界を変えるというアプローチに魅力を感じて、こうしたアプローチができる仕事をしたいと思ったわけです。

ただ、文系だったので、当時ものづくりをするスキルはなかった。そこで、「ソフトウェアエンジニアだったら文系出身でもものづくりができるようになる」という噂を真に受けて、エンジニアの求人に応募しました。そして新卒で1社めのSIerに入社したんです。アプリエンジニアとWebエンジニアの違いもよく分かりませんでしたが(笑)。

三宅悠介さん:GMOペパボ株式会社 ペパボ研究所 研究員/プリンシパルエンジニア。大学卒業後、地元福岡のSIer勤務を経て、2012年より株式会社paperboy&co.(現、GMOペパボ株式会社)に勤務。サービスの運用開発の傍ら、ログ活用基盤「Bigfoot」の構築に取り組み、サービスを動的に改善していくための仕組みづくりと機械学習に興味を持つ。2017年より現職。

──では、プログラミングを始めたのは就職後ということですか。

三宅 そうです。大学の卒論は人差し指でタイピングしていたくらいのリテラシーでした(笑)。入社して少しだけJavaの研修を受けた記憶がありますが、あとは現場に放り込まれて独学でした。とはいえ、1社目ではプログラマというより、セールスサイドに近い仕事が多かったんです。そうしているうちに、もっと技術を突き詰めた仕事がしたいと思って転職を考えるようになり、「福岡 IT おもしろい」とかで検索したらペパボが見つかったので、応募したんです。すごい場当たり的ですね(笑)。一度は落ちてしまったんですが、どうしても入社したかったので、二度目のチャレンジで無事入社できました。

──ストレートな転職活動ですね(笑)。エンジニアリングにのめり込んでいくきっかけはあったのですか。

三宅 転職にあたって、なんらかのアウトプットが必要になると思って最初のOSSの開発に取り組んだんです。最初に世に出したものは「BundleSaver」というAndroidのライブラリでした。多くの人が使える共通基盤を作る、と同時に、「問題をフレーミングする」ということに魅力を感じたんですね。例えば、多くの課題があるなかで、「これはAという課題を解決するツール、一方これはBという課題を解決するツール」のように、課題を文字通りフレーム化するのが楽しいと感じたんです。振り返ってみると、こうした考え方は今も大事にしていますね。

三宅さんが最初に送り出したOSS。「アプリ内のデータをストレージに保存する」などの、お決まりの動作をラッピングするというもの。「いま見ると稚拙ですね……」とは三宅さんの弁。

──なるほど。では、どういった課題感から「BundleSaver」を作ろうと思ったんですか?

三宅 単純に、不便だったんです。当時Androidアプリを作っていて、お決まりの作業を手動でやるのが面倒だったのですが、ググっても自動化の手順が出てこないんです。だったら自分で作ってみようと。

開発のヒントは、紙の上にある

──「BundleSaver」は課題ありきの開発だったのですね。では、今回特にお伺いしたい「The Platinum Searcher」の場合はどうでしょうか。どのような経緯で開発されたのですか。

三宅 開発当時、サービスの運用開発を担当していたのですが、その中である課題に直面したんです。

──やはり課題発進だったのですね。どんな課題だったのですか。

三宅 ペパボの提供するサービスも歴史が積み重なってくると同時に、レガシーなコードも積み重なり、全貌を把握している人が少なく、メンテナンスしにくい状況だったんです。例えば、画面上に表示されるあるテキストを修正しようとしても、そのためにはどこのコードをいじればいいのか分からない、といった状況です。

多くの場合、全文検索やgrepを使って当該箇所を探すと思いますが、ある日社内の人間から「The Silver Searcher」というOSSを使うと爆速で検索できると聞いたんです。しかし、当時のソースコードはレガシー過ぎて、「The Silver Searcher」が使えないんです。我々のソースコードには文字コードにEUC-JPやShift_JISを使っている部分があったのですが、「The Silver Searcher」は英語圏で作られたものなので、UTF-8を前提に作られていたんです。なので、EUC-JPのファイルを検索しても、バイナリファイルと見なされて、検索対象外になってしまうんです。

我々の古いソースコードの中には「◯年◯月■が作業」といった日本語文字列が残っていたりするので、「The Silver Searcher」で検索すると、欲しい検索結果が大体バイナリファイル扱いされてしまう。全文検索の意味がないけれど、この検索スピードは捨てがたい、ということで自分で作ってみようと考えたんです。つまり、開発の経緯やモチベーションは「仕事がラクになったらいいな」の一念です。

参考:GitHub - ggreer/the_silver_searcher: A code-searching tool similar to ack, but faster.

──極めて現実的な課題解決のためのツールだったのですね。開発にあたってはどのような部分を改変したのですか。

三宅 「The Silver Searcher」のソースコードを読んで、文字コードを判定している部分を見つけて、そこを修正してみました。実際には、受け渡しする文字列と表示する文字列とのソフトウェア内部で整合性をとる、といった修正もしたのですが、全体的に少修正でイメージしたものになってくれました。

──なるほど。作業自体は比較的スムーズだったと。

三宅 いえ、実はここまでの話は「The Platinum Searcher」の前段階にあたる、「Shirogane」というOSSのものです。「Shirogane」は「The Silver Searcher」のFork版でしかなく、当時の僕にとって不慣れなC言語で書かれていました。苦手な言語ではその後メンテナンスなどに対応してくことは難しい、という課題がありました。そして、ちょうどこの頃、弊社のCTOのあんちぽ@kentaroが「これからはGoだ!」盛り上がっていたので、だったらGoの勉強ついでに、習作としてGo版の「Shirogane」、つまり「The Platinum Searcher」を作ってみようと考えたんです。目的があった方が、勉強もはかどりますから。

日本語圏特化型ag -白金- の配備が完了しました · THINKING MEGANE

「The Platinum Searcher」の雛形である「Shirogane」に関しては↑の三宅さんのブログに詳しい。

──Goを勉強し始めて、最初のプロダクトが「The Platinum Searcher」だったのですか。

三宅 そうですね。Goの本を1冊読んで、そこから年末年始の休みの間に作った記憶があります。人に教えてもらうのが苦手なので、基本的に独学です。

──慣れない言語だと、戸惑う部分もあったと思います。苦労したのはどんなところでしたか。

三宅 goroutineや並行処理をイメージできなくてすごく戸惑いましたね。シーケンス図を書きながら、処理の流れを考えるのですが、複数の処理が順不同に並んだ時に、流れが頭の中で思い描けなくなってしまったんです。

開発当初は、例えばディレクトリのトラバース時にgoroutineを立ち上げ、並行・並列で検索することで速度が上がるだろうと考えていたのですが、これをどうやって書いたらいいのかが分からなかったんです。

──どうやって解決したのですか。

三宅 ひたすら構成図を紙に書いたんです。シーケンシャルに動くものではないので、少し粒度を上げて考えればいい、と。たくさんのタスクを並行・並列に流せるように分解して、中と外をつなぐのがchannelなのだろう、とイメージできたら、全体像がつかめてきたんです。処理を1つずつ頭から考えるのではなく、goroutineを立ち上げる単位に処理を細分化する、という考えが、紙に書いていたら見えてきました。

──コードではなく、“紙に書く”というのも重要ですね。

三宅 人によって正解は違うと思いますが、僕は何か分からないものに当たったとき、紙に書くことをよくやります。新卒のときもJavaのnewが理解できなくて、何度も紙に図や絵を書いた記憶があります。自分が納得いくまで、人に説明できるようになるまで書くことは昔からのクセかもしれません。もちろん、普段の仕事や論文を書くときも、まずはイメージを書き出してみます。まあ、それで考えがまとまるとは限りませんが(笑)。

f:id:blog-media:20180717220002j:plain

「The Platinum Searcher」には直接は関係しないが、いまも三宅さんはこのように図や絵を描き、イメージをつかもうと試みる。画像は三宅さんのブログより。

──開発の学習効果は大きそうですね……。「The Platinum Searcher」の開発にあたって、先行する「The Silver Searcher」を参考にした部分はあるのですか。

三宅 あえて「The Silver Searcher」を読まないようにしていましたね。実装レベルではオリジナルと全く異なるGoに置き換えるので共通する部分はほとんどありませんが、「こうした機能のためには、こうしたコンポーネントがこうやって組み合わさる」といった全体的な構成は全て自分でイメージしていきました。

ソフトウェアの振る舞いは「The Silver Searcher」を踏襲していますし、文字コードの判定の部分は参考にしましたが、内部はほぼ全て作り変えていますね。実は、開発の目的に、「The Silver Searcherより速いものを作る」と考えていたのですが、「The Platinum Searcher」のリリース当初はこれが実現できなかったんです。「The Silver Searcher」はかなり多くの人が時間をかけて開発にあたっていたので、当たり前といえば当たり前だったかもしれせんが(笑)。

改訂2版 基礎からわかる Go言語  著:古川 昇 刊:シーアンドアール研究所

独学でGoを学習した三宅さんが参考にしたのはこの1冊だ。上は第2版だが、三宅さんは初版を読み込み、Goを学んだ。

Goの腕試しとして、「5倍速い」ものを作る

──さて、「The Platinum Searcher」は2015年にほぼ書き直しと言ってもいい、大規模なアップデートをしています。これにはどのような背景があったのですか。

三宅 本来、習作だったので改善点はたくさん見つかってきたんです。あと、本家の「The Silver Searcher」が進化していたことも理由です。「The Platinum Searcher」の売りは「日本語が使えて、ワンバイナリで、The Silver Searcher“相当”のスピード」だったのですが、本家の方が速くなってしまい「The Silver Searcher“相当”のスピード」と謳えなくなってしまった(笑)。

リリース以降、さまざまなオプションを追加するなど、「便利さ」を追求して「The Platinum Searcher」をメンテナンスしていたのですが、自分のGoに対する理解も深まったという自信があったので、次は自分に出せる極限の「速さ」を追求して書き直してみようと思ったんです。

「The Platinum Searcher」のチューニング内容に関しては上記スライド、また自身のブログに詳しい。

──新たな「The Platinum Searcher」は、従来型と比較すると5倍の速度を出した、とブログにはあります。どんな要素が速度向上に貢献したのでしょうか。

三宅 全面にわたってチューニングしていますが、最も効果的だったのは文字列検索時のファイル読み込み回数を減らした点ですね。従来は検索されたファイル内の文字列を1行ごとに愚直に読み込んでいたのですが、複数行に対して検索するようにしたんです。また、実装の簡単さから文字コード判定時に別途同じファイルの読み込みを行っていた部分も共通化しました。つまりディスクへのI/O(Input/Output)を減らした、というのが最も効果的だったんです。

ツールの名前=ツールが果たすべき役割

──ブログを読んでいると、嬉々としてベンチマークを測る様子が見え隠れします(笑)。三宅さんの場合、作っていて最も楽しいのは、どんな瞬間ですか。

三宅 実は、ツールの名前を考えている時間が好きなんです。命名には実装と同じくらいの時間をかけているかもしれません。そもそも、名前が決まっていないと、手が動かない(笑)。

さっきもお話した「ツールが果たすべき機能≒機能のフレーミング」を極限まで圧縮して表現したのが、ツールの名前だと思っているんです。逆に言うと、名前がないと仕様が決められないし、名無しで作り始めたものは、だいたいグダグダになってしまいます。仕様と振る舞いをきれいに表現する名前がバシッと決まると、気分が上がりますね(笑)。

「Shirogane」の場合は「The Silver Searcherを日本語対応したもの」というシャレのような命名だったのですぐに思いつきましたが。

──命名に苦労したこともあるのですか。

三宅 「Hoi(ホイ)」というツールですね。大きなサイズのファイルをやり取りするときに、どこかにアップロードして、ファイルパスを伝えて、それをダウンロードしてもらう、という作業って煩雑じゃないですか。こうした作業を簡易化するツールを作りたいなと考えていたんですが、気軽に「ほい、これどうぞ」と手渡すイメージを名前にしたんです。

いってみれば、ただのファイルサーバーなんですが、ただ「なんとかファイルサーバー」という名前にしてしまうと、僕にとってはしっくりこないんです。「Hoi」という名前にすることによって、ソフトウェアの振る舞いや、ユーザに「こういう感じで使ってほしい」というイメージが具合的になるんです。逆に、「ほい、これどうぞ」という振る舞いを実装するためには、「直接ファイルが渡せる」「ファイルの場所を指示できる」というツールに必要な機能も浮かんでくるわけです。

──まさに名前が機能を定義していくんですね。

三宅 そうですね。機能が明確になれば、逆に「やらなくていいこと」も自分の中で明確になりますから。

──独特なプロセスですね。では、命名の前段階、三宅さんにとって開発のきっかけになるものとはなんですか。

三宅 「省力化」と「自分ならどうする?」のどちらかだと思います。「何かの結果を求める時に従来「AをやってからBをやって、最後にCをする」というプロセスだったとしたら、僕の場合できれば「A’くらいの作業」で終わらせたい。そのためのツールを作りたい、というものです。「Hoi」の場合が顕著ですが、従来ファイルをアップロード→ファイルの場所を共有→相手がダウンロード、というプロセスをコマンド1つで解決できるようにする。こうした省力化をイメージできると、開発に取りかかりたくなるんです。

もう一つは、例えばGoでOR Mapperを作るとして「自分だったら、こうやって作る」という場合ですね。この場合、作ったものを使うかどうかは別として、パズルを解くような楽しさがあるように思います。

ツールが果たすべき仕事の粒度

──「The Platinum Searcher」は2,000を超えるスターが付いていますね。Pull RequestやIssueもかなり来ると思いますが、印象に残っているものはありますか。

三宅 そうですね……、「The Platinum Searcher」にページャーを付けたいというIssueが記憶に残っていますね。検索結果が膨大になった際、ページングできるようにしたい、と。「The Platinum Searcher」はフィーチャーリクエスト(追加機能のリクエスト)を受け付けていたのですが、初めて断ったんです。ページャーを付けるのはSearcher(検索ツール)が果たすべき機能ではない、と感じたんです。ですから、相手にはソフトウェアのポリシーとして対応できない。ページャーが必要なら、パイプを使ってlessコマンドで対応してほしい、と。相手は納得してくれましたが、かなりドキドキしながら返した記憶があります(笑)。

きちんとディスカッションをして、ツールが持つべきポリシーをはっきりとさせ、それを伝えると分かってもらえる、という経験が得られたので、印象深いですね。

三宅さんに強い印象を与えたIssueがこちら。ページャー機能がなくとも、「The Silver Searcher」との差別化は可能だと考えたという。

──お話を伺っていると、三宅さんはシンプルな状態を好む、というように感じます。ツールに関しても、シンプルなものを目指しているのでしょうか。

三宅 おっしゃる通りかもしれませんね。複雑なものを考える能力がないだけかもしれませんが(笑)。「困難は分割せよ*1」の言葉もありますが、シンプルな課題に向き合う方が狭く深く考えることができるように思いますし、そういう考え方の方が好きでもあります。

ツールにしても仕事の粒度の小さいものが組み合わさることで、むしろ大きな機能を果たすとも思います。

──ただ、難しいのは「シンプルの度合い」だと感じます。粒度の設定と言い換えてもいいと思いますが、「このツールは、この仕事をする」という粒度の設定はどのように行っているのですか。

三宅 改めて言葉にしようとすると難しいですね……。さっきお話したツールの命名を考えている時に、適切な仕様はいろいろと考えていますが……、ちょっと1分だけ考えていいですか。

──はい。

三宅 ……やっぱり難しいですね(笑)。ただ、強いて言えば、ツールを中心に考えるのではなく、「入力と出力」を考えると、果たすべき機能の粒度が見えてくるように思います。

入力がユーザーからの入力なのか、他のコマンドからの入力なのか。こうした入力に対して、何を出力するべきなのか……。こうしたことを考えると、必然的に粒度は定まってくるのではないでしょうか。こじつけのような答えですが(笑)。

OSSは世界と関わる媒介

──独学、そして内省が三宅さんの開発の基盤にあるように感じます。OSSを作るとは、三宅さんにどのような意味があるのでしょうか。

三宅 オープンソースではない、という状態はもはや考えられません。オープンにして損したと感じたことは一度もないので。たとえ、誰も見ていなかったとしても、OSSを送り出すことで自分の頭の中を整理もできますし、仮に遠回りだったとしてもスキルアップにもつながっているはずです。「The Platinum Searcher」を開発した話を東京で開催されたGo Conference 2014で講演して、それが自分にとっての自信にもなりましたから。

──現在は、ペパボで研究職としてお仕事をされていますが、OSS活動と研究活動はどのように影響しあっていると感じますか。

三宅 OSSの開発と研究をあまり切り離して考えてはいないんです。OSSの開発は課題を見つける、その課題を解決する手段を作る、フィードバックを受けてさらに磨く、というサイクルだと思いますが、研究活動はその先に「論文を書く」というプロセスが加わった、と解釈しています。研究だから普段の開発と異なるアプローチをするかというと、そうではありません。

──両者は地続きの関係なんですね。

三宅 論文にするとなると、なんらかの「新規性」が求められます。例えば作り出したOSSをテーマにするのであれば、「どこが新しいのか、本当に新しいのか」という要素をOSSから抽出する必要があります。こうした新規性を考えていると、自分がやってきた仕事や強みが明確になることがあります。研究で得られたこうした強みを、次のOSSに生かせることもあると思うので、OSS開発と研究活動はいい関係性にあると感じます。

──なるほど。独学好きであっても、オープンソースから受ける影響は大きいわけですね。

三宅 OSSやコミュニティというものを“媒介”として考えられるようになってきたんです。僕が関わるのは、自分で作ったOSSや自分の主催する小さなコミュニティです。そうしたOSSやコミュニティというアウトプットを誰かが使ってくれて、場合によってはサービスとして世に出る。ここで世界と接点ができるわけです。

僕が直接的に世界につながる、とは考える必要はなくて、GitHubにあるリポジトリを介して、距離も時間も超えて世界と関われる。常に広大な世界と直接関わろうと思ったら疲れちゃうじゃないですか(笑)。

──自分の作ったもので世界を変えてやろう、とは思わないと。

三宅 もちろん、できれば変わってほしいと思っています。ただ、あまりに意識高く意気込んでいたら、逆に「世界を変えられなかったとき」にいちいち落ち込むじゃないですか(笑)。そうではなく、あくまで自分のOSSがどこかで活用されて、世界に関わっている……。こんな距離感でいいと思います。

──気が楽になりそうですね。

三宅 弊社の若いエンジニアにもいつか伝えたいのですが、OSSだからと無理に意気込む必要はない。自分が向き合うのは、自分が解決したい課題や、そのためのソフトウェアだけでいい。ただ、それを公開しておくと必ずメリットがあると思います。

関連記事

取材:megaya megayaのブログ

*1:16世紀の哲学者・数学者ルネ=デカルトが著書「方法序説」に記した言葉。