毎年2月と8月はGoの新バージョンがリリースされます。2021年2月は1.16です。本ブログでは1.16のリリースを記念してGo 1.16の新機能を紹介する集中連載を行います。現時点のリリースノートはこちら。次のような内容を考えています。乞うご期待。
公開日 | 寄稿者 | 記事 |
---|---|---|
2月8日 | 伊藤真彦 | Go 1.16からリリースされたgo:embedとは |
2月9日 | 真野隼記 | Go 1.16のgo installについて |
2月10日 | 辻大志郎 | Go1.16からのio/ioutilパッケージ |
2月12日 | 澁川喜規 | Go 1.16のsignal.NotifyContext() |
本エントリーは、これら以外にどんな変化があったのかをダイジェストで紹介します。
アーキテクチャ対応: M1のmacに対応
今回も新しいアーキテクチャの追加が行われていますが、一番大きいのはApple Siliconの正式対応でしょう。2ヶ月ほど前に対応コードがmasterにマージされたタイミングで当ブログでもすでに紹介していました。
もともとdarwin/arm64はiOS向けでしたが、これはios/arm64にリネームされました。c-archive, c-shared, pieモードも使えるし、race detectorも利用可能です。
すでに計測値を出していましたが、Rosetta以外をRC1で再計測してみました。M1は高速な結果から、さらに全体的にはすべての結果が1割近く改善していました。amd64は処理系が安定していて、差があっても誤差かな? というものが多かったです。いくつか、M1が他のCPUに負けていた項目だけピックアップしたのが次の表です。他のものより8倍遅かったCRC32は4倍改善され、2倍遅いぐらいで差が詰まっています。ParseBoolは1割ほど高速したものの、他との差は大きいですね。SHA1とSHA256は大幅改良で他を圧倒する速度を手に入れています。全体的に他のCPUとの差をさらに広げつつ、負けているところもかなり減ってきていますね。残っている大負けしているテストはrosetta2にも負けているということでGoのランタイムのコードが改善されたら治るはずで、M1のハードウェア起因ではなさそうですね。
M1 (12/3のmaster→RC1) | M1(rosetta) | Core i5-1030G7 (12/3のmaster→RC1) | Ryzen 9 4900HS (12/3のmaster→RC1) | |
---|---|---|---|---|
BenchmarkBlake3256-8 | 6339→5733 | エラー | 3460→3764 | 2782→2849 |
BenchmarkCRC32-8 | 1098→255.5 | 139.2 | 140.5→143.5 | 163.7→169.8 |
BenchmarkFnv128-8 | 4924→4465 | 7617 | 3448→3598 | 6084→6026 |
BenchmarkMD5-8 | 3566→3198 | 4345 | 3283→3209 | 2635→2603 |
BenchmarkSHA1-8 | 5789→899.9 | 4247 | 2924→3177 | 2041→2086 |
BenchmarkSHA256-8 | 10865→914.8 | 7832 | 6361→6473 | 4346→4612 |
BenchmarkSHA512-8 | 7801→6997 | 3987 | 4685→4816 | 2939→3224 |
BenchmarkMathAtomicInt32-8 | 7.132→6.888 | 7.864 | 6.562→6.015 | 4.258→4.149 |
BenchmarkMathAtomicInt64-8 | 7.07→6.918 | 7.758 | 7.079→5.890 | 4.231→4.167 |
BenchmarkMathMutexInt-8 | 12.45→13.68 | 15.07 | 18.69→15.58 | 8.776→8.589 |
BenchmarkParseBool-8 | 1.598→1.430 | 0.3529 | 0.3532→0.3147 | 0.3208→0.5364 |
VSCodeも1.53でInsiderでない安定板もM1対応になりますし、GoLandもネイティブ版がリリースされました。Rosetta2でも快適だった環境はますます快適になっています。
それ以外だとlinux/riscv64対応が改良されていて、個人的には気になっています。
ランタイムの変化
runtime/metricsパッケージが導入されました。runtimeとかdebugとかさまざまな場所に散っていったメトリックス収集機能が集約されました。今サポートしているのはGC関連のメトリックスと、メモリ関連のメトリックス、goroutine数ですね。
あとは、GODEBUG環境変数にinittrace=1を設定すると、各パッケージのinit
で消費している時間やメモリの情報が標準出力に表示されます。Google App EngineやらCloud RunやらCloud FunctionsやらAWS Lambdaやらでインスタンス数ゼロからのコールドブート時間を減らしたいサーバーレス愛好家にとってはタピオカミルクティー🧋並に人気が出そうな新機能です。
init compress/flate @1.2 ms, 0.027 ms clock, 4240 bytes, 7 allocs |
ツールの変化
go.mod対応周りが大幅に変わったことと、embed対応が大きなトピックです。これはそれぞれの紹介のなかで詳しく説明されます。
1.15で加えられたリンカーの更新がELFベースのOS/amd64だけだったのが、ありとあらゆる環境に適用され、速度は20-25%高速に、メモリ使用量は5-15%ほど削減されています。
それ以外は比較的小さい変化で、go testで、os.Exit(0)もエラーとなるように変更されたりとかですかね。あとは-overlayでファイルのパスの読替のJSONを読み込ませることができ、ファイルの動的な置き換えが可能になるという変更もありますが、これは未セーブのファイルを別のパスに書き出しておいてデバッグ実行するといったように、エディタ側から使われることを意図しているようでした。
1.16でレジスタベースの関数呼び出し規約が入ってパフォーマンスアップというのを報じるメディアもありましたが、それは1.17に先送りされたようです。次も楽しみですね。
ライブラリの変化
全部を紹介するのは細かすぎるので、気になるポイントだけピックアップします。
大きいのはembed追加に伴って導入されたio/fsと、io/ioutilが非推奨化されたことですね。リリースノートで大きく取り上げられています。また、いくつかのパッケージがio/fs対応で機能追加されています。
また、小さい関数追加のsignal.NotifyContext()
は個人的にうれしかったので連載で取り上げます。
netパッケージではErrClosed
というエラーのインスタンスが追加されました。1.13でerrorsパッケージが更新されてエラーチェックの共通の方法としてerrors.Is()
が導入されましたが、それとの比較が行いやすいように、いままで非公開だったエラーのインスタンスが公開されました。新しく提案された使い方に合わせて、全体が統一されていくのは良いですね。
strconvのParseFloat()
は新しいアルゴリズムを使うことで最大二倍高速になりました。これを使っているencoding/json
も高速になるとのこと。
time/tzdataがスリムなデータ構造を使うようになってバンドルサイズが小さくなったとかもありました。
個人的に面白かったのがコードのパーサーのライブラリの更新で、Go 1.17で導入予定の新しいbuild constraintのコメント形式をサポートするというものです。Go 1.17のソースを処理するツールを今から書けますよ、とのこと。
// 今の書き方 |
おまけで、Unicodeのバージョンが13になりましたので、ランタイムのところに書いた↑タピオカミルクティーの絵文字🧋がGoで使えるようになりました。
1.17以降の変更
すでに説明した関数呼び出しのレジスタベースの関数呼び出しでパフォーマンスアップが計画されています。
注目度が高いジェネリクスは今のところ2022/02の1.18ぐらいになると言われていますが、ジェネリクスのプロポーザルが2/4にlikely acceptフェーズになりました。Goのワークフロー的には「ディスカッションがコンセンサスに到達。最後のコメントを受け入れる期間」となっています。かなりリリースが近づいてきていますね。
2/11更新: 1週間たって、ジェネリクスのプロポーザルがacceptedになりました。
Generics in #golang has moved to "likely accept" phase...https://t.co/hmA4ofLztV
— Brad Fitzpatrick (@bradfitz) February 3, 2021