2ちゃんねる ■掲示板に戻る■ 全部 1- 最新50    

■ このスレッドは過去ログ倉庫に格納されています

Go language part 4

1 :デフォルトの名無しさん:2020/11/16(月) 04:14:40.64 ID:fB5+0hxC.net
Goについて扱うスレッドです。
GoはGoogleによって開発された言語です。

公式
https://golang.org

公式ドキュメント
https://golang.org/doc/

公式外パッケージドキュメント
https://godoc.org

ブラウザ上で試し書き
https://play.golang.org


※前スレ
Go language part 3
https://mevius.5ch.net/test/read.cgi/tech/1571315884/

952 :デフォルトの名無しさん:2022/02/26(土) 12:16:18.51 ID:pDCyYMqI.net
総じて知らんだけでは?

953 :デフォルトの名無しさん:2022/02/26(土) 12:35:54.23 ID:Zen8kEK8.net
わからせようとするのが無駄だって何で気づかないかな

954 :デフォルトの名無しさん:2022/02/26(土) 12:41:19.24 ID:D1V+AmSx.net
>>940
論理構成がしっかりしてて読みやすければ長文でもいいんだけどね
このおじさんはそこが壊滅的だから明らかに素質ないわな

955 :デフォルトの名無しさん:2022/02/26(土) 12:50:12.55 ID:xkMoRRzB.net
抽象化できず同じ事何回も書く傾向にあるから、凄いコード書きそう

956 :デフォルトの名無しさん:2022/02/26(土) 12:58:01.48 ID:862GBE0V.net
>>955
というか、
短い=良い
もしくは
simple=beautiful
というセンスが欠落している。
あんな汚い長文ぞっとするわw
まあ.{50}でNGにしてるけど

957 :デフォルトの名無しさん:2022/02/26(土) 13:27:19.11 ID:fRC8OZTs.net
Goの(疑似スレッド+)goroutineのパフォーマンス計測っていいやつないの?
↓見つけたやつ
Goroutines Are Not Significantly Smaller Than Threads
https://matklad.github.io//2021/03/12/goroutines-are-not-significantly-smaller-than-threads.html

958 :デフォルトの名無しさん:2022/02/26(土) 13:41:54.09 ID:CoGWNwI7.net
Goってぶっちゃけ言語機能とか割とどうでもよくて、
・ビルドやデプロイや運用がシンプル
・本家の開発体制が保守的で、長期的に安定したサポートが期待できる
という点がメリット
極力作りっぱなしで放置したい類のものに向いてると思うんだよね
Goしかできない奴やGo大好きで使ってる奴もまずいないだろうし、こんなもん執拗に叩いて何がしたいの

959 :デフォルトの名無しさん:2022/02/26(土) 13:51:01.17 ID:bMt+E6tQ.net
CLIツールはともかく一番使われてるWeb APIは放置したいものとは対極だろう

960 :デフォルトの名無しさん:2022/02/26(土) 14:05:08.22 ID:nWQ4XblH.net
APIはむしろどっちかというと放置したい系じゃね?
フロントと表裏一体みたいなのもあるけど、そういうのにGoはあまり採用されないでしょ

961 :デフォルトの名無しさん:2022/02/26(土) 14:21:48.69 ID:yRlIqUsp.net
確かにそうだな。わかろうとしないし、伝わらない気がしてきた。
Rust最高とRustスレで言っててくれれば良いか。

>>958
これはあるよね。
1つ前のバージョンどころか、それなりに昔のGoのプログラムですら修正せずにコンパイルできる。

962 :デフォルトの名無しさん:2022/02/26(土) 16:17:55.72 ID:kpnhrKVl.net
>>951
やってないのはやる必要がないから。
他言語も馬鹿ではないので、改善の努力はしてるし、いい点があったら平気でパクってる。

(Goはgreenthreadで全て解決!と謳っているわけではないけども、そうだとしたら)
そのアイデアは面白かったが、現実的ではなかった。
(ただしこれはランタイムの問題だから改善の余地はあるはず)

非同期はコードがうざくなるのは事実だが、async文法でほぼ払拭された。
だからみんなパクってる。


まあ完全にループだし、材料枯渇でここら辺で終わりかな。
そりゃ信者の念仏を何度聞いても翻意する事はないよ。俺は文系ではないし。
こちらの見解では説明出来ないデータが出て来たら、分析して、考えを修正するけど。



>>957
virtualの40MBを単純に合算したら、今は4倍軽くて、4k/goroutine時代は2.5倍軽かったという事か。
フットプリントだけの比較ではあるが。
だから極めて単純に言えば、他言語のスレッドでジョブを4つずつ束ねて処理する運用をすれば、
フットプリントでは並んで、速度は余分なスケジューラが入ってない分勝てる事になる。

963 :デフォルトの名無しさん:2022/02/26(土) 17:32:36.09 ID:nY3OEggH.net
>>960
そりゃWebのフロントエンドに比べりゃなんだって放置したい系になるだろ
Webの場合はバックエンドでもWebフレームワークをサポートバージョンに維持する必要があるから
長くても3〜5年すればコードを変更することになる

964 :デフォルトの名無しさん:2022/02/26(土) 17:33:24.82 ID:117KIGn2.net
>>958
言語機能は本当に20世紀に設計された言語なのかと
疑いたくなるね
ほぼGCがあるCを書いてる感覚に近い
C書けない人が書ける言語じゃないと思う

965 :デフォルトの名無しさん:2022/02/26(土) 18:00:31.99 ID:yRlIqUsp.net
>>962
はい、じゃあ言質も取れたのでRustスレに戻って下さいね

966 :デフォルトの名無しさん:2022/02/26(土) 18:06:45.33 ID:yRlIqUsp.net
>>963
そうか?コアAPIに関してはあんまり手を入れないけどな。
Webフレームワーク次第なAPIってどんなの?

967 :デフォルトの名無しさん:2022/02/26(土) 18:16:48.89 ID:nWQ4XblH.net
>>966
SPAのすぐ裏でUIの要件に合わせて作るようなやつのことじゃね?
そういうのはそもそもGoを採用しないと>>960で書いた通りだ

968 :デフォルトの名無しさん:2022/02/26(土) 19:00:50.19 ID:yRlIqUsp.net
>>967
なるほど。BFF的なやつ。
たしかにGoで書くまでもないし、ノンコーディングもあるよね。

969 :デフォルトの名無しさん:2022/02/26(土) 19:13:38.66 ID:nWK21oqu.net
正直なんだかんだ言って、学習コストに対しての性能パフォーマンスが異様に高いというところがGoの魅力
言語仕様がコンパクトだからミスしにくい(気がする)のも良い
チャネルに容量があることを忘れるうっかりさん以外には

得意な機能は限られててGUIとかは苦手だけど、そんなもんC#やらに任せとけばいいや

970 :デフォルトの名無しさん:2022/02/26(土) 19:41:27.25 ID:cxVkNmoR.net
Goの魅力はケン・トンプソンなんよ

https://en.wikipedia.org/wiki/Ken_Thompson#2000s
> When the three of us [Thompson, Rob Pike, and Robert Griesemer] got started, it was pure research.
> The three of us got together and decided that we hated C++. [laughter] ... [Returning to Go,]
> we started off with the idea that all three of us had to be talked into every feature in the language,
> so there was no extraneous garbage put into the language for any reason.

彼が"we hated C++"つって作っただからそらもうみんな嬉しいやろ

971 :デフォルトの名無しさん:2022/02/26(土) 19:44:13.98 ID:fRC8OZTs.net
結局>>957よりいいパフォーマンス計測ってないのかー
個人的感想としては。。。
パフォーマンスについて特筆すべき利点はない
原理的にスレッドプールを使った他言語のコードと同程度の性能が出る
機能的な利点はグリーンスレッドを言語で持っており、自動でOSスレッドと使い分けられる点(記述量低&必要メモリ低)
逆に欠点はスケジュールをコントロールする方法がGOMAXPROCS以外ない点ってところかな

972 :デフォルトの名無しさん:2022/02/26(土) 20:07:50.21 ID:nWK21oqu.net
>>971
優先度がないのはちょっぴり残念ではある
…ないよね?

973 :デフォルトの名無しさん:2022/02/26(土) 20:31:14.25 ID:kpnhrKVl.net
>>969
> 学習コストに対しての性能パフォーマンスが異様に高い
Cの方が高いけどな。Goよりも小さい仕様で速い。
あとC#もGUIはゴミだぞ。それ以外がいいからunityを制覇してるが。

974 :デフォルトの名無しさん:2022/02/26(土) 21:20:48.95 ID:4mZJSMD8.net
>>943
>> それはN:M軽量スレッドだからなし得ることなので、他の言語ができてない以上何とも比べづらい。

RustもM:Nモデルだよ
Goと同じく複数の非同期タスクを複数のOSスレッドに割り当て
しかもGoとは異なりスタックレスなのでGoよりも軽量タスクを実現しているよ

>>951
>> スティーリングまでやるのは他の言語の言語標準機能にはErlangぐらいにしかない。

RustもGoと同じM:Nモデルでワークスティーリングもしているよ
Rustでは以下のランタイムを選ぶことができるよ
・1:1モデル (=M:Mモデル、OSスレッドそのまま利用)
・M:1モデル (シングルOSスレッドで並行マルチタスク)
・M:Nモデル[スレッドプール方式]
・M:Nモデル[ワークスティーリング方式]

975 :デフォルトの名無しさん:2022/02/26(土) 21:35:40.76 ID:yRlIqUsp.net
>>974
それは処理系標準?それとも準標準?

976 :デフォルトの名無しさん:2022/02/26(土) 21:58:06.53 ID:kpnhrKVl.net
>>974
それ以下と定義が同じだと、一般的には「ワークスティーリング方式」を「スレッドプール」と呼称するよ。(だからC#のもこれのはずだけど)
https://tech-blog.optim.co.jp/entry/2019/11/08/163000
Rustで何故あえて方言にしているのかは知らん。
というかワークスティーリングじゃない方のメリットなんてない気がするんだが。

977 :デフォルトの名無しさん:2022/02/26(土) 21:58:10.74 ID:nPeFYJEF.net
>RustもGoと同じM:Nモデルでワークスティーリングもしているよ

VMじゃないのにどうやって実現してるのかな

978 :デフォルトの名無しさん:2022/02/26(土) 21:59:12.46 ID:4mZJSMD8.net
>>975
RustはGoと真逆で標準ライブラリとは最小限のものに限る位置付けなので
標準ライブラリには非同期ランタイムを作るための枠組みだけが存在していてランタイム自体は無しだよ
これは全ての分野について同じ方針でRustでは標準+準標準(デファクトスタンダード)を使ってプログラミングをするよ

979 :デフォルトの名無しさん:2022/02/26(土) 22:13:34.76 ID:4mZJSMD8.net
>>976
そこは一般的は話としてまずOSスレッド毎にキューと持つかグローバルにキューを持って割り振るかの2大方式があるよ
それぞれに利点と欠点があってそこは省略するけど
GoもRustもそのハイブリッド方式となっていて普段はスレッド毎にキューを持って各OSスレッドが独立に効率よく処理だね
そしてGoもRustもグローバルにも管理して暇なOSスレッドが生じるとそこへ割り振る(OSスレッドから見るとスティール)するよ
詳細はここで書ききれないほどもう少し複雑だから省略してる点はそれぞれの解説サイトなどを見てね

980 :デフォルトの名無しさん:2022/02/26(土) 22:54:22.46 ID:kpnhrKVl.net
>>979
Goと同じなら805のリンクの内容と同じだからああそうですか程度。
資料が古いがC#のは以下で確認した。同様にハイブリッドでスティーリングもあり。
(ただ.NET6.0とかだともう変わってそうだが)
https://ufcpp.net/study/csharp/misc_task.html
基本グローバルキューで、ただし優先順位はローカルキュー>スティーリング>グローバルキューになってる。
この構造はまあ納得。

> GoもRustもそのハイブリッド方式となっていて普段はスレッド毎にキューを持って各OSスレッドが独立に効率よく処理だね
> そしてGoもRustもグローバルにも管理して暇なOSスレッドが生じるとそこへ割り振る(OSスレッドから見るとスティール)するよ
無駄に複雑で余計に遅くなると思うけどね。.NETの方が単純ですっきりしてていい。
グローバルキューから取り出す時の競合を気にしてるのなら、
Goみたいに100,000goroutineとか目指す場合は分かるけど、Rustは基本そうじゃないだろうから、チューニングミスだと思うけど。

981 :デフォルトの名無しさん:2022/02/26(土) 23:02:07.46 ID:Gc6jVciw.net
Goは別に最速を目指している言語じゃないからね
もし何かのベンチマークが最速になってしまったら逆に驚くよ
そのベンチ間違ってるだろ、って。

982 :デフォルトの名無しさん:2022/02/26(土) 23:40:35.78 ID:BX4iLvdt.net
>>977
VMじゃないと起きる問題点は何?
いずれにせよC/C++/RustはVMでもOSでも記述できるのだからそこに不可能は無い

>>980
言語に関係なくシステムスレッド間のグローバルな操作はデータ競合回避など一定のコストがかかる
だから可能な限り個別にシステムスレッドが動くようにしつつアイドルが出ないよう最小限のグローバル操作
この部分はよほど上位で制約のある仕様としていないならば全ての言語で同じ

983 :デフォルトの名無しさん:2022/02/26(土) 23:48:39.58 ID:yRlIqUsp.net
>>978
これがなぁ…。過渡期は混ぜるな危険で困らない?そこが不安。
Rustも良いとは思うんだけど、爪切るのにハサミ使ってる気分になる。

984 :デフォルトの名無しさん:2022/02/26(土) 23:59:29.99 ID:kpnhrKVl.net
>>982
それはハードによる。
x86はハードウェアでキャッシュコヒーレンシを取ってくれるので実は共有RAMでもコストは安い。
.NETがローカルキューからの取り出しでFIFOとFILOで競合が減るから、というのはそういう事。
Goの場合はARMを見てるのか、MacがARMに乗り換える布石だったのか、
以前からやたら「共有RAMは遅いから使わない」としてきてるが、
ぶっちゃけx86の場合は
(書き込み頻度と量によるが、タスクの起動=関数ポインタ1つと引数のポインタ程度なら)
OSを利用したチャネル接続よりも共有RAMの方が実は速い。
ここら辺を理解してない奴がグダグダやってるからチューニングし切れてないのだと思うよ。

985 :デフォルトの名無しさん:2022/02/26(土) 23:59:34.35 ID:4mZJSMD8.net
>>980
>> Goみたいに100,000goroutineとか目指す場合は分かるけど、Rustは基本そうじゃないだろうから、

Rustの非同期タスクはGoroutineよりも更に軽くて
Goとは異なりスタックレスなので付加メモリ消費も非同期ランタイムの管理データ分の1タスクあたり64bytesで済みますよ
そしてグローバルキュー競合コストの件は>>982のように同じですね

986 :デフォルトの名無しさん:2022/02/27(日) 00:02:30.74 ID:2GGoVw4G.net
>>982
問題があると言っているわけじゃなくて、VMやOSじゃなければプリエンプションできないからどうやっているのかなと。

987 :デフォルトの名無しさん:2022/02/27(日) 00:03:38.38 ID:uWHjNeVw.net
>>973
Cはお爺ちゃんだから…
Cからの乗り換えコストっていう視点でどうかひとつ

あ、でも実装系別の頭おかしくなるコンパイルオプションやらバウンダリやらのメモリモデル考えると、Goのほうが実質勝ってないか学習コスト?

988 :デフォルトの名無しさん:2022/02/27(日) 00:11:21.81 ID:uWHjNeVw.net
>>973
ちなみに速さやらサイズでは当然にCとかの圧勝だろ普通に
関数呼び出しごとにオーバーヘッドのかかるGoが単純な速度で勝てる道理はない

989 :デフォルトの名無しさん:2022/02/27(日) 00:23:35.14 ID:uWHjNeVw.net
>>973
C#というか.Netのwpfは好き
一般的な手法じゃないだろうけど、MVVMのVM部分を単体テストできて(ディスパッチャ細工してメインスレッドで走らせる)

990 :デフォルトの名無しさん:2022/02/27(日) 00:44:59.79 ID:PVy06kKY.net
>>985
> Goとは異なりスタックレスなので
やたらこれを強調しているが、goでもgoroutineにローカルキュー(=関数ポインタの配列)を用意して、順に食わせれば、
各タスク毎にスタックを用意する必要なんて無くて、普通にエミュレーション出来るよ。
(ただしGo信者的にはこれは負けだからやらないとも思うが)

ただこの場合、各タスクが止まらない前提ならこれでいいが、
止めて切り替える分には一般的にはスタック領域が必要になる。
(自動変数を全部ヒープ上に確保すればスタック無しでもいいが、これは遅くなるので多分やってないと思う)
ユーザーが確保しなくていいだけで、実際はランタイムかコンパイラが確保してくれてるだけじゃないか?

991 :デフォルトの名無しさん:2022/02/27(日) 00:50:50.94 ID:PVy06kKY.net
>>988
> 関数呼び出しごとにオーバーヘッドのかかるGo
かからないような気がするが、自信はない。かかる理由って何?

992 :デフォルトの名無しさん:2022/02/27(日) 02:41:36.05 ID:uWHjNeVw.net
>>991
Goは関数呼び出しごとにスタックをチェックして、不足してたなら拡大するから
関数ごとの静的な自動変数サイズと比較してるだけだと思うけど、そういう処理のおかげで初期スタックサイズを抑えてる
https://postd.cc/performance-without-the-event-loop/

993 :デフォルトの名無しさん:2022/02/27(日) 02:47:33.19 ID:uWHjNeVw.net
>>991
「十分な空間がない場合、ランタイムはヒープに対して大きなスタックセグメントを割り当て、現在のスタックの内容を新しいセグメントにコピーし、古いセグメントを解放し、それから関数呼び出しを再開します。」

994 :デフォルトの名無しさん:2022/02/27(日) 03:00:02.25 ID:uWHjNeVw.net
>>991
毎回拡張する訳じゃないけどそのためのチェックは毎回走るんで、単にサブルーチンを呼ぶだけの他言語よりは余分な仕事をしている
おそらくチェックは必要な回数だけだとは思う(ループ内での呼び出しとかの最適化は考えてないとは思わないから)

995 :デフォルトの名無しさん:2022/02/27(日) 06:52:35.32 ID:+yReYAPt.net
compiler explorer(https://godbolt.org/)で、goコンパイル結果を普通のamd64用のアセンブラ見ること出来ないの?(Plan9でなく)

996 :デフォルトの名無しさん:2022/02/27(日) 07:42:28.85 ID:uWHjNeVw.net
次スレ建ててくる

997 :デフォルトの名無しさん:2022/02/27(日) 07:44:00.44 ID:uWHjNeVw.net
Go language part 5
https://mevius.5ch.net/test/read.cgi/tech/1645915400/

998 :デフォルトの名無しさん:2022/02/27(日) 07:56:25.05 ID:nXG/aSfD.net
>>990
Rustの非同期タスクは内部的には単純な状態マシンとなり何度も再入可能なコルーチンと同じ状況になります
その中の変数はRustのクロージャがその環境の変数をキャプチャするのと同じだからもちろんメモリを確保します
だからスタックレスで何度も呼べるクロージャみたいな状況でスタック自体はプロセス全体で1本のままとなります
もちろんその非同期タスクから他の非同期でない普通の関数を呼べば通常と同じくスタックが伸びて使われていきます
一方でその非同期タスクから他の非同期な関数を呼ぶとその非同期タスクから一旦離脱してスケジューラーへ戻ります
最初に書いたように「単純な状態マシンとなり何度も再入可能なコルーチン」となっているので再び再開できます
以上がスタックレスなのにRustの非同期タスクがメモリの許す限り多く動くことができる仕組みです

999 :デフォルトの名無しさん:2022/02/27(日) 08:07:16.26 ID:c9v4owXb.net
ワッチョイ無しかー(´・ω・`)

1000 :デフォルトの名無しさん:2022/02/27(日) 08:16:41.16 ID:+yReYAPt.net
goroutineとC++標準ライブラリのスレッドを比較するために>>957のmain.rsのC++版だけ作ってみた(ループは一桁減らした)
$ cat main.cc
#include <thread>
#include <chrono>
#include <vector>
using namespace std;
using namespace std::chrono;
int main() {
vector<unique_ptr<thread>> threads;
for (uint32_t i = 0; i < 1000; ++i) {
threads.emplace_back(
make_unique<thread>([=]{
uint64_t bad_hash = (i * 2654435761) % 200000;
this_thread::sleep_for(microseconds(bad_hash));
for (uint32_t _ = 0; _ < 1000; ++_) {
this_thread::sleep_for(10ms);
}
})
);
}
for (auto const& t: threads) {
t->join();
}
return 0;
}
$ g++ -O3 -pthread main.cc -o main && ./t ./main
real 11.04s
user 0.93s
sys 2.95s
rss 11328k
$
結果はmain.rsとほぼ同じで、やはりスレッド起動コストがデカく、rssもデカい

1001 :2ch.net投稿限界:Over 1000 Thread
2ch.netからのレス数が1000に到達しました。

総レス数 1001
320 KB
掲示板に戻る 全部 前100 次100 最新50
read.cgi ver.24052200