pecoに入った修正をみて、果たしてchanはいくつまで付けられるのか気になったので、
雑に試してみました。
先に断っておきますが、全く有用ではないですよ。
背景
pecoに入った修正はこちら(一部抜粋)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | |
channelを使ってchannelをやり取りすることができるので、
chan struct{}をやり取りするchan chan struct{}という型が使えます。
同じ要領で、channelをやり取りするchannelをやり取りするchannelをやり取り…するchannelが
無限に作れるはずです(少なくとも構文上は)。
ということで、実際にやってみました。
実験
雑なPerlスクリプトを準備して、大量のchanを付けたGoのコードを自動生成します。
1 2 3 4 5 6 7 8 9 10 11 12 13 | |
chanの個数を変えて何度かビルドを繰り返します。
1
| |
結果
chanの個数とビルドにかかった時間をまとめてみました。
| chanの個数 | ビルド時間 |
|---|---|
| 1 | 0.236s |
| 2 | 0.240s |
| 4 | 0.226s |
| 8 | 0.234s |
| 16 | 0.240s |
| 32 | 0.250s |
| 64 | 0.281s |
| 128 | 0.258s |
| 256 | 0.360s |
| 512 | 0.775s |
| 1024 | 3.228s |
| 2048 | 18.605s |
| 4096 | 1m53.614s |
| 8192 | 13m46.018s(ビルド失敗したので参考記録) |
8192個付けたら以下のようなエラーを吐いてビルドが失敗してしまったので、 8192個の時の記録は参考記録です。
1 2 | |
何かビルドの設定をいじればもっと行けるかもしれませんが、
デフォルトの設定では4096から8192の間に限界があるようです。
4096個chanを付けたときのソースコードは20KB程度なのにバイナリサイズは524MBまで膨らんでいました。
256個当たりからビルド時間に影響が出ているので、
ビルド時間を考える256個以下に抑えるのがよさそうです。
それ以上だと 程度のオーダーでビルド時間が延びます。
とはいえ、256個もchanを付いたコードを人間が読めるとは思えないので、
2個が限度でしょうね・・・。
3個以上必要になるケースは余りないと思います。
型定義を再帰的にして無限chanを実現する
そもそも、chanを大量に並べなくとも、
型定義を再帰的に行えば無限のchanを付けたときと同等のことができます。
例えば以下のコードで"Goroutine 1"と"Goroutine 2"を交互に表示することが可能です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | |
channelでのやり取りが複雑になるので実用性があるかは不明ですが・・・。 例えば先程の例だと、普通にループを書いたほうが圧倒的にシンプルです。
1 2 3 4 5 6 7 8 9 10 11 12 13 | |
無限chanが必要になる多くのケースは、このような書き換えができるような気がします。
(そもそも必要になったことがない)
まとめ
chanの個数の上限は4096から8192の間のどこか- 256個あたりからビルド時間に影響が出始める
- プログラムを読む人の精神力に多大な影響を与えるので、実際は2個までに留めるべきだと思う
- 再帰的に型を定義することで、無限に
chanを付けた時と同等のことが可能
chanを大量に付けたいケースには今までに僕自身は遭遇したことがないです。
有用な例を見つけた人は教えてください。