如果“数字”的输入量已知(合理),一种解决方案可能是将所有可能的输入组合存储在某些数据结构中,这将有助于快速访问。一个这样的例子是MapN
class(尽管它可以用普通的数字阵列轻松完成)。我公司将提供一个小例子来说明这个想法(包括基准):
function allResults = q43095156(allResults)
if nargin == 0
% Let's store all combinations of 8 binary digits:
in = uint8(0:255);
out = uint16(in)+uint16(in.');
outB = logical(de2bi(out(:),'left-msb'));
[in1,in2] = meshgrid(in,in);
allResults = MapN(...
num2cell([num2cell(in1(:),2),num2cell(in2(:),2)],2),...
num2cell(outB,2));
end
benchmark(allResults);
end
function benchmark(allResults)
rng(43095156);
a = logical(randi([0 1],10,8,'uint8'));
b = logical(randi([0 1],10,8,'uint8'));
% Test:
R{5} = de2bi(bi2de(a,'left-msb') + bi2de(b,'left-msb'),'left-msb');
R{4} = add_a_bunch_gnovice(a,b);
R{3} = add_a_bunch_Sardar(a,b);
R{2} = add_a_bunch_dato(a,b);
R{1} = getFromMap(a, b, allResults);
assert(isequal(R{:}));
% Benchmark:
a = logical(randi([0 1],1000,8,'uint8'));
b = logical(randi([0 1],1000,8,'uint8'));
fprintf(1,'\nSardar''s method:\t%f',timeit(@() add_a_bunch_Sardar(a, b)));
fprintf(1,'\nDev-iL''s method:\t%f',timeit(@() getFromMap(a, b, allResults)));
fprintf(1,'\ngnovice''s method:\t%f',timeit(@() add_a_bunch_gnovice(a, b)));
fprintf(1,'\ndato''s method:\t\t%f',timeit(@() add_a_bunch_dato(a, b)));
fprintf(1,'\nbi2de method:\t\t%f',timeit(@() de2bi(bi2de(a,'left-msb') + bi2de(b,'left-msb'),'left-msb')));
end
function out = getFromMap(a,b,map)
out = cell2mat(values(map, num2cell([ num2cell(bi2de(a,'left-msb'),2),...
num2cell(bi2de(b,'left-msb'),2)],2)));
end
function out = add_a_bunch_gnovice(a,b)
out = zeros(size(a)+[0,1],'logical');
for ind1 = 1:size(a,1)
out(ind1,:) = add_binary_gnovice(a(ind1,:), b(ind1,:));
end
end
function out = add_a_bunch_Sardar(a,b)
out = zeros(size(a)+[0,1],'logical');
for ind1 = 1:size(a,1)
out(ind1,:) = add_binary_Sardar(a(ind1,:), b(ind1,:));
end
end
function out = add_a_bunch_dato(a,b)
out = zeros(size(a)+[0,1],'logical');
for ind1 = 1:size(a,1)
out(ind1,:) = add_binary_dato(a(ind1,:), b(ind1,:));
end
end
function s = add_binary_gnovice(a, b)
a = [0 a];
b = [0 b];
c = a&b;
while any(c)
b = xor(a, b);
a = circshift(c, -1);
c = a&b;
end
s = a+b;
end
function s = add_binary_Sardar(a,b)
s = logical(str2double(num2cell(dec2bin(bin2dec(num2str(a)) +...
bin2dec(num2str(b)), numel(a)+1))));
end
function s = add_binary_dato(a,b)
m = length(a);
s = zeros(m+1,1);
n = length(a);
c = 0;
for ii = n:-1:1
d = floor((a(ii)+b(ii)+c)/2);
s(ii+1) = a(ii)+b(ii)+c-2*d;
c = d;
end
s(1) = c;
s = logical(s.');
end
而且随着我的x64 MATLAB R2017a @ Win10的结果是:
Sardar's method: 0.336414
Dev-iL's method: 0.061656
gnovice's method: 0.022031
dato's method: 0.002123
bi2de method: 0.000356
所以这应该给我们一个想法,方法是更快(除非我搞砸了包装功能大涨)...
的MapN
方法的好处是明显的,如果金额的计算是一些其他的,昂贵的操作。
不是应该'S =零(M + 1,1)' – Suever
耶,我看到它,它是错字,但仍具有一些缺陷 –
'str2double(num2cell(dec2bin(bin2dec(num2str(a))+ bin2dec(num2str(b)))))' –