golang/go の master ブランチに行われたコミットから個人的に気になったものをリストにしたものです。
前回作成したリストはこちら。
軽く説明を追加していますが勘違いや誤りがあるかもしれません。
Topic
- ジェネリクスで使用するタイプパラメータに interface{} を省略してそのままタイプセットを書けるようになりました。
- 文字列を 2 つに分割する strings.Cut が追加されました。
- ビルドしたバイナリにバージョン管理情報やビルド時の指定が埋め込まれるようになりました。
- パフォーマンスを理由として wasm で使用される syscall/js から js.Wrapper が削除されました。
- Go に workspace サポートが追加されました。
- sync.Mutex にロックされている場合はブロックせずに戻ってくる TryLock メソッドが追加されました。
Commits
2021-10-01
ジェネリクスで使用するタイプパラメータに interface{} を省略してそのままタイプセットを書けるようにする変更です。 1
constraints パッケージを使うより分かりやすい記述になっています。
2021-10-02
タイムアウトなどで名前解決に失敗した際に一貫して net.DNSError を返すようになります。 2
これによりエラーの原因を調べやすくなります。
Context.Value による値の取り出しが再起呼び出しからループに変更されています。 3
Context はネストされやすく、短命な goroutine では再起呼び出しによるスタックサイズ変更がそれなりのコストになるようです。
2021-10-05
シンボル情報の配置を見直すことでロード時間の短縮やリンク時のメモリ消費を削減しているようです。
goroutine 起動か関数呼び出しのオーバーヘッドを改善しているようです。
正直なところよくわかっていません。
2021-10-06
小さなサイズの定数との比較を最適化しているようです。 4
encoding/binary のエンディアン系関数を使っている場合にインライン化されやすくなりました。 5
bytes や strings で ASCII 文字を trim する際のパフォーマンスが大幅に改善されています。 6
8 月に行われていた改善 7 では 1 文字限定でしたが複数文字の場合も改善されました。
http.Cookie に値が有効かチェックする Valid メソッドが追加されました。 8
文字列を 2 つに分割する strings.Cut の追加と置き換えが行われています。
標準ライブラリの使用実態を調査したうえでより分かりやすい関数として実装されたようです。 9
次の記事で strings.SplitN と比較されていました。
追加の目的は効率ではないとされていますが結果的に効率も改善されたようです。
2021-10-07
指定値未満のランダムな整数値を取得する処理が fastrand() % n からより速い fastrandn() に変更されています。
両方とも runtime で定義されている関数で fastrand() 自体も一部の CPU で xorshift64+ から wyrand になっていたようです。 10 11
32 bit 環境にて uint64 から float32 への変換で丸め誤差が出る不具合の修正です。 12
この commit だけでは不十分だったらしく追加の修正も行われています。 13
wasm_exec.js に大きな引数を与えると wasm モジュールの一部を書き換えてしまう脆弱性修正です。 14
この修正はバックポートされ Go 1.17.2 と Go 1.16.9 がリリースされています。
2021-10-08
time.ParseDuration() で int64 の最小値を parse できなかった問題が修正されています。 15
最小値を設定する機会はないと思うのですがこの修正で性能向上しているのが面白いです。
2021-10-09
WaitGroup の Example Test に含まれている URL が example.com に修正されました。 16 17
ドキュメントに書く URL はちゃんと考えたほうがよさそうです。
encoding/binary に関連した最適化のようです。
amd64 と arm64 にて 8 BYTE のデータを swap 命令を 2 回呼んでコピーしているのを 1 個の move 命令に置き換えています。 18
2021-10-11
正規表現に UTF-8 として無効な文字が与えられた場合の挙動が修正されています。 19
これまでは一貫性がなかったらしいのですが U+FFFD と同じとみなされるように統一されるようです。
本来は U+FFFD とも一致しないのが正しいですが既存動作を壊してしまうため妥協したようです。
2021-10-12
image/gif が出力した GIF 画像の互換性問題を解消するために compress/lzw が修正されています。 20 21
amd64 にて定数値が 32bit に収まる場合の ANDQ を ANDL に書き換える修正です。
これにより Linux x86_64 バイナリが 0.03% 小さくなるとのことです。
性能への影響もあるようですが良くなるものと悪くなるものが混在しているようです。
2021-10-14
ビルドしたバイナリにバージョン管理情報やビルド時の指定を埋め込むための修正です。 22
これまでは ldflag などで git の commit ハッシュなどを埋め込んでいましたが runtime から取得できるようになります。
また、実行ファイルのバイナリから埋め込まれた情報を取得する debug/buildinfo パッケージが追加されています。
この後も追加の修正が行われており最終的に Git, Mercurial, Fossil, Bazaar がサポートされたようです。
https サーバーで ReadHeaderTimeout は設定しているが ReadTimeout を設定していない場合に TLS handshake がタイムアウトしない問題が修正されています。 23
2021-10-18
for や switch が含まれる関数もインライン化できるようになったようです。 24
パフォーマンスを理由として wasm で使用される syscall/js から js.Wrapper が削除されました。 25 26
非互換の変更となりますが syscall/js は実験的な扱いのパッケージで互換性の約束を免除されています。 27
2021-10-19
64 bit アーキテクチャの場合に WaitGroup で行っているアライメントチェックを省略することでパフォーマンスを改善しています。
ドキュメントの修正です。
errors.Is は一致するエラーが見つかるまで unwrap するのでユーザーが実装した Is メソッドで errors.Unwrap を呼び出すべきではないとしています。
Go に workspace サポートを追加するための変更です。 28
設定は go.work というファイルに書くようです。
2021-10-25
mask が image.Alpha の場合の DrawMask のパフォーマンスを改善しています。 29
2021-10-26
ビルドしたバイナリに VCS のコミット時刻も含まれるようになりました。
2021-10-27
ジェネリクスで使用するタイプパラメータに interface{} を省略してそのままタイプセットを書けるようになったため constraints パッケージから Slice/Map/Chan が削除されました。
2021-10-28
range を含む関数もインライン化できるようになったようです。
2021-10-29
sync.Mutex にロックされている場合はブロックせずに戻ってくる TryLock メソッドが追加されました。 30
ただし、ほとんどの場合で TryLock の利用は好ましくないと考えているようです。
Windows 環境でクラッシュダンプが作成できるようになったようです。 31
GC をいつ動かすか決定するアルゴリズム (GC Pacer) を再設計するための修正の一部です。 32
感想
Go 1.18 の目玉機能ということもあってジェネリクス関連の修正が多いのですがそれ以外にも多数の改善が行われていました。
また、リストには書いていないのですが GOAMD64 指定による性能改善もいくつかありました。
ビルド環境より実行環境のほうが古いこともあるので自動設定されると怖いですがうまく使えば新しい CPU の恩恵を受けられそうです。