最近何かと話題のChatGTP。だけど、めっちゃ凄いってのは分かっていても具体的に何が凄いのかが分からない。。なんて方も多いはず。
今回は特にエンジニア勢に刺さる、プログラムの性能改善についてChatGTPにお願いすることで、ChatGTPの凄さについて感じてもらいたい。
どういう質問に対してどういうコードが提示されたか、その結果どう改善したかを紹介する!
ChatGTPにお願いしたこと
今回は、テストデータ作成ツールを作り、このツールの性能改善をお願いすることにした。
ファイルインターフェースを扱う場合、そのファイルを手作業で作成するのは結構面倒くさい。
データバリエーションは要らないので、ひたすらデカいデータファイルを作りたい。なんて場合も現場では多いはず。大量データ試験とかに利用する想定とする。
で、基本的に日本の開発現場ではWindowsなので、Windowsに標準搭載されているPowerShellで作成してみた。
てわけで、まずはそのソースを紹介する。
因みにこれ書いたのは自宅なので、自分の仕事している開発現場では残念ながら使えない。アイデアとしては使えるかも知れない。
改善前のプログラムと処理性能
まずは改善前のプログラムを紹介。
改善前プログラムのソースコード
軽く仕様を説明すると、
「ヘッダ、データ、トレーラを含む固定長ファイルを、入力値分データレコードを用意して生成したい」
というもの。
ファイルイメージはこんな感じ。↓
20230416
0000000001
0000000002
0000000003
0000000004
0000000005
0000000005
ヘッダ(1行目)とトレーラ(最終行)にそれぞれ実行日付とデータ件数、データ部には仮想の処理キーとして連番を割り当てている。
以下が実ソースとなる。
Start-Transcript "log.txt"
$fileName = Read-Host "ファイル名を指定してください(指定がない場合:dataFile_yyyyMMddHHmmssとなります)"
$dataNum = Read-Host "データレコードの件数を指定してください"
Measure-Command {
if ([string]::IsNullOrEmpty($fileName)) {
# 入力されたファイル名が空の時は、デフォルトのファイル名を付与
$formatted_date = (Get-Date).ToString("yyyyMMddHHmmss")
$fileName = ("dataFile_" + $formatted_date)
}
# ヘッダレコードを書き込み(実行時の日付 + 半角スペース2つ)
$hed_date = (Get-Date).ToString("yyyyMMdd")
Set-Content $fileName ($hed_date + " ")
# データレコードの書き込み(10桁の連番をデータレコード分インクリメントして設定)
for ($i=0; $i -le $dataNum -1; $i++) {
# を充てる(10桁で前0埋め)
$acc = "{0:D10}" -f ([int]$i + 1)
# データレコードの追記
Add-Content $fileName ([string]$acc)
}
# トレーラレコードを書き込み
$trNum = "{0:D10}" -f ([int]$dataNum)
Add-Content $fileName ([string]$trNum)
}
pause
Stop-Transcript
とりあえず動作確認はしているので動くには動くが、正直なところ結構雑に作っているので、無駄は全然あると思っている。だけど、可読性は悪くないはず。
改善前プログラムの処理性能(10万件)
上のプログラムには処理時間を表示するコードを埋め込んでいるので、実際に動かして時間を図っていきたいと思う。
Transcript started, output file is log.txt
Days : 0
Hours : 0
Minutes : 16
Seconds : 10
Milliseconds : 139
Ticks : 9701394544
TotalDays : 0.0112284659074074
TotalHours : 0.269483181777778
TotalMinutes : 16.1689909066667
TotalSeconds : 970.1394544
TotalMilliseconds : 970139.4544
処理にかかった時間は16分10秒だった。
待てる人には待てるのかも知れないが、10万件のデータレコードを作るだけにしては時間がかかりすぎている。
今回はこの残念性能なコードをChatGTPにお願いして、性能改善をしてみることにする。
ChatGTPへのお願い
“以下のpowershellコードのパフォーマンスを改善して”
と言う依頼を出し、上で紹介したソースコードを添付してみた。
これに対し、ChatGTPはこんな感じで返してくれた。
ソースコードのパフォーマンスに関する具体的な改善案に加え、その改善点を修正した版のソースコードを提供してくれた。
指摘についてはかなり具体的だし、めっちゃ的を得ていると思う。
特にファイルの書き込みについては書いている自分でも絶対パフォーマンス悪くなると思っていた箇所だし、この手のスクリプト言語はループ内処理をいかに検討するかがパフォーマンスに大きく影響するのは身を持って体感している。
例えば似たような言語で開発現場で触りがちなのだとBashシェルとか。ツールであれば、今回のPowerShellだったり、VBScriptとかが当てはまる。
と、まあひとまずChatGTPへのお願いと回答はこんな感じだった。
改善後のプログラムと処理性能
さて、ここからはChatGTPが改善してくれたソースコードを見ていこう。
改善後プログラムのソースコード
Start-Transcript "log.txt"
$fileName = Read-Host "ファイル名を指定してください(指定がない場合:dataFile_yyyyMMddHHmmssとなります)"
$dataNum = Read-Host "データレコードの件数を指定してください"
Measure-Command {
if ([string]::IsNullOrEmpty($fileName)) {
# 入力されたファイル名が空の時は、デフォルトのファイル名を付与
$formatted_date = (Get-Date).ToString("yyyyMMddHHmmss")
$fileName = ("dataFile_" + $formatted_date)
}
# ヘッダレコードを書き込み(実行時の日付 + 半角スペース2つ)
$hed_date = (Get-Date).ToString("yyyyMMdd")
$header = $hed_date + " "
# StringBuilderを使用してデータレコードを連結
$dataRecords = [System.Text.StringBuilder]::new()
$acc = 1
while ($acc -le $dataNum) {
$dataRecords.Append("{0:D10}" -f $acc)
$dataRecords.AppendLine()
$acc++
}
# トレーラレコードを連結
$trNum = "{0:D10}" -f [int]$dataNum
$trailer = [string]$trNum
# StreamWriterを使用してファイルに書き込む
$streamWriter = [System.IO.StreamWriter]::new($fileName)
$streamWriter.WriteLine($header)
$streamWriter.Write($dataRecords.ToString())
$streamWriter.WriteLine($trailer)
$streamWriter.Close()
}
pause
Stop-Transcript
ChatGTPが自ら示してくれた改善案がしっかり盛り込まれたソースコードとなっている。
もともとはデータレコードをループ内で書き込んでいたため、10万件を処理対象とした場合、10万件の書き込みが走るという地獄みたいなソースだったが、書き込み数はヘッダ、データ、トレーラで1回のみとなった。有言実行じゃないか。
そして、地味に凄いと思ったのは、このコードの仕様面も把握してそうなところ。しっかり変数名が$header、$dataRecords、$trailerとなっている辺りからそれが伺える。
しかも、個人的に入れたかったファイル名のロジックだったり、ログ出力についてはちゃんと残してくれていると言う配慮。マジで優秀過ぎる。
改善後プログラムの処理性能(10万件)
改善後と同じ10万件を処理してみた。
Days : 0
Hours : 0
Minutes : 0
Seconds : 26
Milliseconds : 825
Ticks : 268253741
TotalDays : 0.000310478866898148
TotalHours : 0.00745149280555556
TotalMinutes : 0.447089568333333
TotalSeconds : 26.8253741
TotalMilliseconds : 26825.3741
処理にかかった時間は26秒。なんと改善前と比較すると実に15分くらいの処理性能の違いだ。10万件でこの処理性能の差が出るわけだから、実際の業務で想定し得る100万件、1,000万件のデータを捌いたときにはもっと大きい差が出るはず。
全く同じ内容のファイルを作成するのにこれだけ処理時間が変わるのだから、パフォーマンスを考慮したプログラムを行うことがいかに重要なのかが良く分かる。
何はともあれChatGTPを利用した性能改善は間違いなく成功と言っていい。
所感
ChatGTPにやってもらいたい事が明確で、それを言葉で説明できるのであれば、ChatGTPによるソースコード改善は非常に有益であると感じた。
しかもChatGTPの利用はフリープラン(無料)で可能。これが無料で使えるなんて、正直信じられないし、使わないのはもったいない。
まだまだ日本の企業はChatGTPの利用に慎重だし、なかなか今すぐ開発現場で利用出来るようにはならないかも知れないが(少なくとも自分はそう)、現状でもプライベートでアイデアを出すのには使えるし、サンプルコードの作成とかにも使える。
最近はAIで画像作成したり、文章を書いたり、今回みたいにプログラムを書いたりと、様々なことが簡単にできるようになっている。
まだ触ったことがない人も、食わず嫌いせずに是非一度触れてみて欲しい。きっと思うことがあるはずだから。
最後に
動かないおじさんを無理に使うより、色々できるChatGTPを無料で使うほうがみんな不幸にならなくていいぞ。おじさん?知らんわ。