両方の質問に対する答えは、マップを使用することです。これを行うには、いくつかの手順があります。
まず、bit_array を数値または文字列に変換する関数が必要です。たとえば、 に変わり[0 1 1 0 1 0]
ます'011010'
。(Matlab はスカラー キーまたは文字列キーのみをサポートしているため、この手順が必要です。)
マップ オブジェクトの定義
cachedRunMap = containers.Map; %See edit below for more on this
特定のケースが実行されたかどうかを確認するには、 を使用しますiskey
。
cachedRunMap.isKey('011010');
実行の結果を追加するには、追加構文を使用します
cachedRunMap('011010') = [0 1 1 0 1]; %Or whatever your result is.
キャッシュされた結果を取得するには、取得構文を使用します
tmpResult = cachedRunMap.values({'011010'});
これにより、システム メモリが不足するまで、値を効率的に保存および取得できます。
これをまとめると、コードは次のようになります。
%Hacky magic function to convert an array into a string of '0' and '1'
strFromBits = @(x) char((x(:)'~=0)+48); %'
%Initialize the map
cachedRunMap = containers.Map;
%Loop, computing and storing results as needed
for i=1:1000000000
%pick a bit array somehow
strKey = strFromBits(bit_array);
if cachedRunMap.isKey(strKey)
result = cachedRunMap(strKey);
else
result = complex_function(bit_array);
cachedRunMap(strKey) = reult;
end
%do something with result
end
文字列ではないキーが必要な場合は、ステップ 2 で宣言する必要があります。いくつかの例を次に示します。
cachedRunMap = containers.Map('KeyType', 'char', 'ValueType', 'any');
cachedRunMap = containers.Map('KeyType', 'double', 'ValueType', 'any');
cachedRunMap = containers.Map('KeyType', 'uint64', 'ValueType', 'any');
cachedRunMap = containers.Map('KeyType', 'uint64', 'ValueType', 'double');
aKeyType
を設定すると'char'
、文字列をキーとして使用するようにマップが設定されます。他のすべての型はスカラーでなければなりません。
これをスケールアップする際の問題について(最近のコメントによる)
セッション間のデータの保存: システム メモリの制限まで、このマップを *.mat ファイルに保存しても問題はありません。
古いデータの消去: このマップに LRU 機能を追加する簡単な方法を知りません。Java 実装を見つけることができれば、Matlab 内で非常に簡単に使用できます。そうしないと、キーが最後に使用された時間を追跡する最も効率的な方法を決定するのに、ある程度の考慮が必要になります。
同時セッション間でのデータ共有: ご指摘のとおり、これにはおそらくデータベースが効率的に実行される必要があります。DB テーブルは 2 つの列 (LRU 機能を実装する場合は 3 つ)、キー、値 (および必要に応じて最後に使用された時間) になります。「結果」が SQL に簡単に適合しないタイプ (たとえば、不均一なサイズの配列や複雑な構造) の場合は、それを格納する方法をさらに検討する必要があります。また、データベースにアクセスする方法も必要です (たとえば、データベース ツールボックス、または Mathworks ファイル交換のさまざまなツール)。最後に、実際にサーバー上にデータベースをセットアップする必要があります (たとえば、私のように安価な場合は MySql、または最も経験が豊富な場合、または最もヘルプを見つけることができる場合)。これは実際にはそれほど難しいことではありませんが、最初は少し時間と労力がかかります。
考慮すべきもう 1 つのアプローチ (効率ははるかに劣りますが、データベースは必要ありません) は、データ ストアを多数 (たとえば、数千または数百万) のマップに分割することです。それぞれを個別の *.mat ファイルに保存し、そのマップに含まれるキー (文字列キーの最初の N 文字など) に基づいたファイル名を付けてから、必要に応じてセッション間でこれらのファイルをロード/保存します。これはかなり遅くなります...使用状況によっては、毎回ソース関数から再計算する方が速い場合があります...しかし、DBをセットアップせずに考えることができる最良の方法です(明らかにより良い答えです)。