2

パラメータとしてマップを受け入れるメソッドを持つscalaコンパニオンオブジェクトがあります。次に、このマップを別のコンパニオン オブジェクト内の別の関数に変更なしで渡します。また、メソッドの実行が速いと、実際のメソッド呼び出しに時間がかかりすぎます (すべてを測定しました)。マップを渡さない場合 (代わりに null を使用) は高速に動作しますが、引数として渡すと、実際のメソッド呼び出しは非常に遅くなります。

私は何かが欠けていますか? Map が再作成されており、参照が渡されるだけではありませんか?

object ContentElementParser {
    def parse(node: Node, assets: Map[String, Asset]): Option[ContentElement] = {
        //Some logic here
        AssetParser.getAsset(subNode, assets) //this call is too slow because of assets map
    }
}

object AssetParser {
    def getAsset(node: Node, assetMap: Map[String, Asset]): Asset = {
        //logic
    }
}
4

2 に答える 2

4

参照渡しです。他にも何かが起こっています-マップを初めて使用するときに測定しているため、クラスのロードも必要です(その後の呼び出しははるかに高速になります)。または、マップを渡すときに、null、またはメモリがほとんど不足しており、代わりにガベージ コレクション時間を測定しています。

スコープに暗黙的な変換があった場合はコピーできますが、型シグネチャが両方の場所でまったく同じである場合は、「変換なし」が常に優先されるため、問題にはなりません。

parse呼び出しのバイトコードは次のとおりです ( を生成するために にメソッドcontentが追加され、を埋めるために にメソッドが追加されています):AssetOption[ContentElement]subNodesubNode

def parse(node: Node, assets: Map[String, Asset]): Option[ContentElement] =
      AssetParser.getAsset(node.sub, assets).content


public scala.Option parse(Node, scala.collection.immutable.Map);
  Code:
   0:  getstatic     #19; //Field AssetParser$.MODULE$:LAssetParser$;
   3:  aload_1
   4:  invokevirtual #25; //Method Node.sub:()LNode;
   7:  aload_2
   8:  invokevirtual #29; //Method AssetParser$.getAsset:
                            (LNode;Lscala/collection/immutable/Map;)LAsset;
   11: invokevirtual #35; //Method Asset.content:()Lscala/Some;
   14: areturn

見る?地図のコピーはありません。 渡されるマップです。 viaaload_2に渡されることを除いて、何も起こりません。getAssetinvokevirtual

于 2013-07-23T21:47:54.707 に答える