Skip to content

Commit

Permalink
Re #1786 Added get_val_for_keys method which gets all values for arra…
Browse files Browse the repository at this point in the history
…y of keys and is 2 times faster then if taking the keys one by one.
  • Loading branch information
abuts committed Feb 10, 2025
1 parent 52a89bc commit d657471
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 3 deletions.
15 changes: 13 additions & 2 deletions _test/test_utilities_herbert/fast_map_vs_map_performance.m
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
n_keys = 500;
n_keys = 100;
base_key = 10+round(rand(1,10*n_keys)*(10*n_keys-1));
base_key = unique(base_key);

Expand All @@ -7,7 +7,7 @@
keysUint = uint32(base_key);
mm = min_max(keysUint)

n_operations= 100000;
n_operations= 10000;


test_keys = repmat(base_key,1,n_operations);
Expand Down Expand Up @@ -52,6 +52,12 @@
tv = toc(tv);
fprintf('Find keys in FAST MAP map takes %gsec\n',tv)

tv = tic;
idx1 = fm.get_values_for_keys(test_keys);
tv = toc(tv);
fprintf('Find all keys in FAST MAP map takes %gsec\n',tv)


fm.optimized = true;
tv = tic;
for i=1:n_idx
Expand All @@ -60,6 +66,11 @@
tv = toc(tv);
fprintf('Find keys in FAST MAP Opt map takes %gsec\n',tv)

tv = tic;
idx1 = fm.get_values_for_keys(test_keys,true);
tv = toc(tv);
fprintf('Find all keys in FAST MAP opt map takes %gsec\n',tv)



function [idx,map] = add_to_map(map,value)
Expand Down
43 changes: 43 additions & 0 deletions _test/test_utilities_herbert/test_fast_map.m
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,49 @@
end
%------------------------------------------------------------------
%------------------------------------------------------------------
function test_get_all_val_for_keys_optimized_no_checks(~)
n_keys = 100;
base_key = 10+round(rand(1,10*n_keys)*(10*n_keys-1));
base_key = unique(base_key);
n_keys = numel(base_key);
val = 1:n_keys;

fm = fast_map(base_key,val);
fm.optimized = true;

valm = fm.get_values_for_keys(base_key,false);

assertEqual(val,valm);
end

function test_get_all_val_for_keys_optimized_with_checks(~)
n_keys = 100;
base_key = 10+round(rand(1,10*n_keys)*(10*n_keys-1));
base_key = unique(base_key);
n_keys = numel(base_key);
val = 1:n_keys;

fm = fast_map(base_key,val);
fm.optimized = true;

valm = fm.get_values_for_keys(base_key,false);

assertEqual(val,valm);
end

function test_get_all_val_for_keys(~)
n_keys = 100;
base_key = 10+round(rand(1,10*n_keys)*(10*n_keys-1));
base_key = unique(base_key);
n_keys = numel(base_key);
val = 1:n_keys;

fm = fast_map(base_key,val);
valm = fm.get_values_for_keys(base_key);

assertEqual(val,valm);
end
%------------------------------------------------------------------
function test_insertion_in_optimized(~)
n_keys = 100;
base_key = 10+round(rand(1,10*n_keys)*(10*n_keys-1));
Expand Down
35 changes: 34 additions & 1 deletion herbert_core/utilities/classes/@fast_map/fast_map.m
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,38 @@
function nm = get.n_members(obj)
nm = numel(obj.keys_);
end
%
function val = get_values_for_keys(self,keys,no_validity_checks)
if nargin<3
no_validity_checks = false;
end
if ~no_validity_checks && self.optimized_
valid = keys<=self.min_max_key_val_(2) | keys<self.key_shif_;
if ~all(valid)
error('HERBERT:fast_map:invalid_argument',...
'All input keys must be in the allowed keys range [%d,%d]', ...
self.min_max_key_val_);
end
end
n_keys = numel(keys);

key = uint32(keys);
val = nan(size(keys));
if self.optimized_
for idx = 1:n_keys
val(idx) = self.keyval_optimized_(keys(idx)-self.key_shif_);
end
else

for idx=1:numel(keys)
present = self.keys_ == key(idx);
if any(present)
val(idx) = self.values_(present);
end
end
end
end

end
methods(Access=protected)
function ks = check_keys(obj,ks)
Expand Down Expand Up @@ -199,7 +231,8 @@
% Overloaded indexers. DESPITE LOOKING NICE, adding them makes fast_map
% 40-60 times slower even without using indexes itself. Disabled for this
% reason, until, may be mex is written which would deal with fast part
% of indices.
% of indices or we fully switch to MATLAB over 2021a, where you may
% overload subsagn using inheritance and special funtions.
methods
% function varargout = subsref(self,idxstr)
% if ~isscalar(self) % input is array or cell of unique_object_containers
Expand Down

0 comments on commit d657471

Please sign in to comment.