2

Python のバックグラウンドを持ち、Go を使い始めたばかりの私は、Go の map() および reduce() 関数に相当するものを探していることに気付きました。私はそれらを見つけられなかったので、for ループに戻りました。たとえば、これは map() の代わりに使用したもので、mapFunction は別の場所で定義されています。

data := make([]byte, 1024)
count, err := input.Read(data) // error handling removed from this snippet
for i:=0; i<count; i++ {
    data[i] = mapFunction(data[i])
}

これは、reduce() の代わりに使用したものです。コードがスライス内の各項目を移動するときに、CSV 内のフィールドの引用を追跡するために使用している 2 つの状態変数があります。

data := make([]byte, 1024)
count, err := input.Read(data) // error handling removed from this snippet
for i:=0; i<count; i++ {
    data[i], stateVariable1, stateVariable2 =
        reduceFunction(data[i], stateVariable1, stateVariable2)
}

ここに私の質問があります:

  1. 私が見逃した組み込みの機能はありますか?
  2. これらのそれぞれに可変スライスを使用するのは適切ですか?
  3. map() にゴルーチンを使用するのは良い考えでしょうか? これにより、ファイルを読み取る IO 操作と、各項目でマッピング関数を実行するプロセスを切り離すことができ、したがって並列化が可能になりますか?
  4. 2 つの状態変数は先行するすべてのデータによって定義されており、順次処理を進める必要があるため、reduce() 関数にはゴルーチンは適していないというのは正しいでしょうか。言い換えれば、この順次プロセスは並行アーキテクチャの恩恵を受けられないのでしょうか?

ありがとう!

ps - 完全なコードはこちら: https://github.com/dbro/csvquote/blob/go/csvquote.go

4

2 に答える 2

4

要するに:

  1. いいえ、組み込みの map または reduce はありません。
  2. はい。ほかに何か?
  3. いいえ。事前の測定や実際の必要性が証明されていない場合は、そのようなことについて考えないでください。
  4. はい。

少し長い。

  1. Go が機能しない、map/reduce ビルトインがない、または標準ライブラリにない
  2. Goには配列とスライスがあります。どちらも可変です。ほとんどの場合、スライスは自然な選択です。
  3. 時期尚早の最適化... 、もちろん: 処理の読み取りが 1 つのループに入り、入力を bufio.Reader にラップすることは良い考えです。
  4. ゴルーチンは素晴らしいもので、異なるタイプのプログラム構築を可能にしますが、それはすべてに使用できるという意味ではありません。ゴルーチンを導入して完全に明確な for ループを複雑にする必要はありません。
于 2013-05-18T23:19:12.243 に答える
0

Volker は良い答えを出しましたが、それは Go の主な強みの 1 つである同時実行性に対応していません。map/reduce タイプの操作は、「サーバー ファーム」戦略を使用して並列化できます (時期尚早の最適化は別として)。これには、実行する作業を別々のワーカー (ゴルーチン) に送信される作業パケットに分割することが含まれます。Map/Reduce はこれを行うための一般的な方法であり、高次関数と不変のデータ構造が必要です。

Go は、関数型言語ではありませんが、特注の並列分解ができるほど柔軟です。不変性はありませんが、コピー セマンティクスを使用することでエイリアシングを回避できるため、ゴルーチン間で値が交換されるときの競合状態がなくなります。簡単に言えば、共有するときは、構造体へのポインターの代わりに構造体を直接使用します。(さらに、Go1.1 には新しい人種検出機能があります)。

サーバー ファーム パターンは、自己均衡を保つため、高い並列化効率を達成するための優れた方法です。これは、幾何学的な分解 (つまり、ゾーンをまとめてプロセッサに割り当てることでデータのグリッドを共有する) やアルゴリズムの分解 (つまり、パイプラインのさまざまなステージをさまざまなプロセッサに割り当てる) とは対照的です。Go は 3 種類すべてを表現できます。

于 2013-05-19T22:21:47.960 に答える