Ответ на оба вопроса заключается в использовании карты.Для этого есть несколько шагов:
Сначала вам понадобится функция, чтобы превратить ваш 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');
Установка KeyType
из 'char'
устанавливает карту для использования строк в качестве ключей.Все остальные типы должны быть скалярами.
Относительно проблем при масштабировании (согласно вашим последним комментариям)
Сохранение данных между сеансами: не должно быть никакихпроблемы при сохранении этой карты в файл * .mat до пределов системной памяти
Очистка старых данных: я не знаю простого способа добавить функции LRU на эту карту,Если вы можете найти реализацию Java, вы можете использовать ее в Matlab довольно легко.В противном случае потребовалось бы некоторое время, чтобы определить наиболее эффективный метод отслеживания времени последнего использования ключа.
Обмен данными между одновременными сеансами: как вы указали, это, вероятно, требуетБаза данных для эффективного выполнения.Таблица БД будет состоять из двух столбцов (3, если вы хотите реализовать функции LRU), ключ, значение (и время последнего использования при желании).Если ваш «результат» не является типом, который легко вписывается в SQL (например, массив с неоднородным размером или сложная структура), вам нужно будет подумать, как его хранить.Вам также понадобится метод для доступа к базе данных (например, набор инструментов базы данных или различные инструменты для обмена файлами Mathworks).Наконец, вам нужно будет на самом деле настроить базу данных на сервере (например, MySql, если вы дешевы, как я, или что-то, с чем у вас больше всего опыта, или вы можете найти большую помощь.) На самом деле это не так уж сложно, но этоВ первый раз отнимает немного времени и усилий.
Другой подход, который нужно рассмотреть (гораздо менее эффективный, но не требующий базы данных), состоит в том, чтобы разбить хранилище данных на большое (например, 1000 или миллионы).количество карт.Сохраните каждый файл в отдельный файл * .mat с именем файла на основе ключей, содержащихся в этой карте (например, первые N символов вашего строкового ключа), а затем загрузите / сохраните эти файлы между сеансами по мере необходимости.Это будет довольно медленно ... в зависимости от вашего использования может быть быстрее пересчитывать из исходной функции каждый раз ... но это лучший способ, который я могу придумать без настройки БД (очевидно, лучший ответ).