Matlab 如何使模和逻辑索引更快地工作?
考虑以下命令:Matlab 如何使模和逻辑索引更快地工作?,matlab,indexing,Matlab,Indexing,考虑以下命令: c(c>A | c<1) = mod(c(c>A | c<1),A); c(c>A | cA | c您实际上不需要在这里执行任何逻辑索引,因为c>A | cA |数据A |数据A |数据
c(c>A | c<1) = mod(c(c>A | c<1),A);
c(c>A | cA | c您实际上不需要在这里执行任何逻辑索引,因为c>A | c<1
排除的任何值都不会被mod
触及,而且将所有内容传递到mod
可能会更快,而不是通过比较和索引来确定要传递给mod
的值
c = [17 -8 213, 7];
c = mod(c, A);
% 7 2 3 7
但一般来说,对于需要对函数的输入和输出进行逻辑索引的其他函数,您希望将逻辑数组存储在临时变量中,而不是计算两次:
touse = c < 1 | c > A;
c(touse) = mod(c(touse), A);
touse=c<1 | c>A;
c(使用)=mod(c(使用),A);
下面是一个快速的小基准测试,显示了每种方法的相对性能:
function timemod()
sizes = round(linspace(100, 100000, 10));
[times1, times2, times3] = deal(zeros(numel(sizes), 1));
A = 10;
for k = 1:numel(sizes)
data = round(rand(sizes(k), 1) * A * 100);
times1(k) = timeit(@()indexing(data, A));
data = round(rand(sizes(k), 1) * A * 100);
times2(k) = timeit(@()indexing_temp(data, A));
data = round(rand(sizes(k), 1) * A * 100);
times3(k) = timeit(@()mod(data, A));
end
figure
plot(sizes, 1000 * cat(2, times1, times2, times3))
legend({'Indexing', 'Indexing w/ temp', 'No Indexing'})
xlabel('Number of Elements')
ylabel('Execution Time (ms)')
fprintf('Indexing: %0.2f ms\n', mean(times1 * 1000))
fprintf('Indexing with temp: %0.2f ms\n', mean(times2 * 1000))
fprintf('No Indexing or temp: %0.2f ms\n', mean(times3 * 1000))
end
function data = indexing(data, A)
data(data > A | data < 1) = mod(data(data > A | data < 1), A);
end
function data = indexing_temp(data, A)
inds = data > A | data < 1;
data(inds) = mod(data(inds), A);
end
函数timemod()
尺寸=圆形(linspace(100100000,10));
[times1,times2,times3]=交易(零(numel(大小),1));
A=10;
对于k=1:numel(尺寸)
数据=圆形(兰特(尺寸(k),1)*A*100);
times1(k)=timeit(@()索引(数据,A));
数据=圆形(兰特(尺寸(k),1)*A*100);
times2(k)=timeit(@()索引温度(数据,A));
数据=圆形(兰特(尺寸(k),1)*A*100);
times3(k)=timeit(@()mod(data,A));
终止
图形
绘图(尺寸,1000*cat(2,时间1,时间2,时间3))
图例({'index','index w/temp','No index'})
xlabel('元素数')
ylabel('执行时间(毫秒)')
fprintf('索引:%0.2f毫秒\n',平均值(时间1*1000))
fprintf('temp索引:%0.2f ms\n',平均值(times2*1000))
fprintf('无索引或温度:%0.2f毫秒\n',平均值(时间3*1000))
终止
函数数据=索引(数据,A)
数据(数据>A |数据<1)=模(数据(数据>A |数据<1),A);
终止
函数数据=索引温度(数据,A)
inds=数据>A |数据<1;
数据(inds)=mod(数据(inds),A);
终止
这太棒了!非常感谢。我真不敢相信我错过了这个选项……现在我要早点完成我的博士学位;)你能在答案中添加第四个选项吗,其中c1=mod(c,a)
(分配到另一个变量)?在我的机器中是最快的。@EBH你真的用基准代码测试过吗?当你正确地分析它(用timeit
)时,与c=mod(c,a)
相比应该没有真正的区别。@EBH timeit更accurate@EBH