1

matlab では、すべてのクラス メソッドは、最初の引数がオブジェクト自体である通常のメソッドのように見えます。

このようなパラダイムは、クラスが参照によって渡されるため、python などの他の oop 言語ではまったく受け入れられます。一方、matlab は既定でオブジェクトを値渡しします (ハンドル クラスを除く)。

これらすべてから、最も単純なセッター関数 (またはその他のクラス メソッド) を使用すると、オブジェクト全体がコピーされると推測されます。

たとえば、以下は matlab のクラス メソッドのシグネチャです。

classdef foo
  methods
    function obj = set.myParam(obj,value);
    function myfun(obj, value);
  end
end

この場合、fooObj.myfun(5) (または単に myfun(fooObj,5)) を呼び出すと、matlab は fooObj=foo() 全体をコピーしますか?

これは信じられないほど大きなオーバーヘッドではありませんか? すべてのクラス メソッド (およびセッター) のオブジェクト全体をコピーすることは、非常に効率が悪いように思えます。

私は何かが恋しいですか?oopテクニックを使用しながら、matlabでこのような状況を回避する方法はありますか?

このようなパフォーマンスのオーバーヘッドを防ぐために、ハンドル クラスを使用する必要がありますか?

4

1 に答える 1

3

クラスに参照セマンティクスを持たせたい場合は、値クラスではなくハンドル クラスを使用する必要があります。

ただし、既定では MATLAB は引数を値で渡しますが、遅延コピーまたは書き込み時のコピーも使用するため、入力引数を変更する必要がある場合にのみ入力引数のコピーが作成されることに注意してください。さらに、入力引数が構造体またはオブジェクトの場合、変更が必要な部分 (フィールド、プロパティ) のみがコピーされます。

さらに、MATLAB にはインプレース最適化があり、出力引数が入力引数と同じであり、入力引数の操作をインプレースで実行できる場合、コピーを作成する必要はありません。

たとえば、次の関数を考えてみましょう。

function y = timestwo(x)
y = 2*x;

ベース ワークスペース内の変数a(非常に大きな double の配列であるとしましょう) から開始して を呼び出すと、 は関数中に変更されb = timestwo(a)ないため、 のコピーは作成されません。メモリ使用量は、出力引数を割り当てるときにのみ増加します。axy

しかし、この関数を考えてみましょう:

function y = timestwoconj(x)
x = x';
y = 2*x;

関数が変更されるとコピーが作成されるため、関数の実行中にメモリ使用量が増加しますx。の計算時に同じスペースが割り当てられy、関数の終了時に の一時コピーxがクリアされます。

これは、コピー オン ライト動作を示しています。

次の関数も考慮してください。

function x = timestwo(x)
x = 2*x;

ここで、出力引数は入力引数と同じであり、すべての操作はインプレースで実行できます。を呼び出すとa = timestwo(a)、コピーはまったく作成されず、メモリ使用量は増加しません。これは、最適化されたインプレース動作を示しています。

上記のような関数をいくつか実装して大きな配列に適用し、タスク マネージャーでメモリ使用量を確認しながらデバッガーで 1 行ずつ実行してみてください。

function obj = myfun(obj, value)MATLAB で値クラスを実装する場合、通常、メソッドには ではなく ,などの構文を使用しますfunction myfun(obj, value)。メソッドは上記と同じように機能するため、メソッド中にオブジェクトを変更している場合にのみ、オブジェクトがコピーされます。

値クラスを扱っている場合は、それを実現したいと考えています。参照セマンティクスが必要な場合は、ハンドル クラスを使用します。

それが役立つことを願っています!

于 2014-01-27T10:30:01.280 に答える