【ISUCON部】ChatGPTとWebプログラミング
IT技術
はじめに
こんにちは、普段は分析や分析基盤の案件をやっている新田です。
Webアプリの開発もやったことはあるものの、最近はあまりWebを触っていない状態だったんですよね。そんな中、社内で面白そうなISUCON部が発足したのでちょこちょこ参加してみています。
久々にPHPやnginxに触れて新鮮な気持ちになっていたのですが、スコア18万点くらいから話題のChatGPTを実践的なプログラミングに活用してみるとどのくらい役に立つのだろうか? を少し試してみました。
ISUCON部について
ISUCON部の前回の記事はこちら
りっきー部長主導のもとISUCON部で題材とされたのはprivate-isu(Copyright (c) 2016 KANEKO Tatsuya) でした。
Pixiv社の社内ISUCONとして作られたリポジトリだったそうなのですが、その後も手直しされていて広く使われているとてもいい題材です。MacBookで環境構築してみたのですが簡単にすぐ環境を作ることができました。
何か変更をする -> スコアを確認する -> 何か変更をする -> スコアを確認する と作業していくのは、分析コンペなどとも似ていてなかなか中毒性がありますね。
試してみた
まずはこのように大まかに指示を出してみました。(ちなみに課金しているのでGPT-4のモデルを使っています。
アカウント名とパスワードのバリデーション
順にコードを見せていきます。まずはアカウント名とパスワードが定められた形式であるかを検証する関数です。
1function validate_user($account_name, $password) {
2 if (!(preg_match('/\A[0-9a-zA-Z_]{3,}\z/', $account_name) && preg_match('/\A[0-9a-zA-Z_]{6,}\z/', $password))) {
3 return false;
4 }
5 return true;
6}
1. 条件分岐を簡略化
なかなかいいですね。確かにif文で分岐するよりも、boolをそのまま戻り値として返したほうが読みやすくて好きです。
2. 正規表現の最適化
これはどうでしょうか。PHPでは/^xxx$/よりも/\Axxx\z/を使ったほうがいいという話があるようなので、元のコードの方が良さそうです。(個人的にはこの件知りませんでした。)
ハッシュ値を求める関数
次は、ハッシュ値を求める関数です。
1function digest($src) {
2 $src = escapeshellarg($src);
3 return trim(`printf "%s" {$src} | openssl dgst -sha512 | sed 's/^.*= //'`);
4}
1. PHPの組み込み関数を使用する
個人的にPHPにそんなに慣れていないので、ぱっと見どうなっているのかわかっていなかったのですが、シェルでハッシュ値を生成しているんですね。組み込み関数を使用することで確かに効率的にできました。
3. エラーハンドリングを追加する
なぜか例外処理をしていますがPHPの公式ドキュメントを調べたところ、hash関数がfalseを返却するようなケースはないようだったので逆に指摘します。
ChatGPTは基本的にとてもそれっぽい回答をするんですが、その一方で嘘をついていることがあるので注意が必要です。
memcachedでクエリをキャッシュ
ISUCON部でmemcachedでクエリをキャッシュするといいらしいと耳にしたので、ChatGPTで色々相談しながらメインページを以下のように修正しました。
1$app->get('/', function (Request $request, Response $response) {
2 $me = $this->get('helper')->get_session_user();
3 $db = $this->get('db');
4 $memcached = $this->get('memcached');
5
6 $query = '
7 SELECT p.id, p.user_id, p.body, p.mime, p.created_at FROM `posts` AS p
8 INNER JOIN `users` AS u ON p.user_id = u.id
9 WHERE u.del_flg = 0
10 ORDER BY `created_at` DESC LIMIT ' . POSTS_PER_PAGE;
11 $cache_key = md5($query);
12 $results = $memcached->get($cache_key);
13 if ($results === false) {
14 $ps = $db->prepare($query);
15 $ps->execute();
16 $results = $ps->fetchAll(PDO::FETCH_ASSOC);
17 $memcached->set($cache_key, $results, 600);
18 }
19 $posts = $this->get('helper')->make_posts($results);
20
21 return $this->get('view')->render($response, 'index.php', [
22 'posts' => $posts,
23 'me' => $me,
24 'flash' => $this->get('flash')->getFirstMessage('notice'),
25 ]);
26});
この修正でスコアが上がりました。他にDBから取得している箇所も直してみます。
この回答はバッチリのように見えました。クエリとクエリパラメータを結合した文字列からハッシュキーを作っているところが賢いと思いました。
しかし冷静に考えるとDBから取得する処理をまとめて定義したほうがコードがスッキリして良さそうです。
これもよさそうです。ヘルパークラスはすでにあるのでfetchWithCache
関数をベースに微修正して定義して呼び出すようにしました。
まとめ
ChatGPTのプログラミング活用、実際やってみると想像していたよりも有用でいいですね。コードを見せてレビューしてもらうような使い方をすると、Google検索では得られないような指摘が得られるところが特にいいなと思いました。回答に対してさらに質問できるところもいいですね。
その一方で、注意すべき点があることもわかりました。
たまに嘘を言うので見抜く必要がある
ChatGPTはそれっぽい回答を生成してくれるのですが、それっぽい一方で間違ったことを言うことがあります。きちんと自分で考えることと、知らない知識が出てきたら自分で公式ドキュメントや技術記事を調べて裏を取る必要がありそうです。
ChatGPTが言うがままに内容を理解せずにコピペするのは危険
ChatGPTの提示したコードをコピペするだけでなんとなく動いてしまうんですね。だからコードを理解せずに適当にコピペして作業するような人もいるのではないかなあと思いました。そんなことをしていると、そのうち意図せぬ挙動をし始めると思います。
また、今回はオープンソースのリポジトリを使用しましたが、業務でChatGPTを使う場合は著作権や秘密情報などの問題があるので関係各所に確認が必要ということもあります。(レビューを得るような方法で使うのは難しいことが多いと思います。)
ちなみにChatGPTを使いつつ作業を進めて、private-isuのスコアを183099点 -> 286292点 とスコアを伸ばすことができました!
さて、次回は同じくISUCON部参加メンバーのこやまんが何か書いてくれそうです。
ライトコードでは、エンジニアを積極採用中!
ライトコードでは、エンジニアを積極採用しています!社長と一杯しながらお話しする機会もご用意しております。そのほかカジュアル面談等もございますので、くわしくは採用情報をご確認ください。
採用情報へ
競馬が好きです。