我正试图加速我的代码中的主要瓶颈 . 它是将数组元素插入数组的中间 . 这些元素必须一次插入一个,因为我事先并不知道 . 我无法收集它们并立即将它们全部插入,因为稍后出现的元素(以及它们的插入位置)以复杂的方式依赖于更新的数组 .

我推测速度限制是由于两个因素造成的:(1)矢量一次生长一个元素,以及(2)复制插入元素时需要向右碰撞的所有元素 . 因子#2有点简化,因为我怀疑在插入新元素时整个更新的矢量是完整的 . 我认为我没有解决因素#2的解决方案,但我确实尝试了因子#1的一些可能性 - 即预分配 .

以下测试表明,我尝试的替代方法无法改进我当前的方法(无预分配) . 测试使用内部循环迭代地将新元素插入到数组的位置2中 . out循环只是重复执行此测试100次以获得更好的定时统计数据 .

clc; Ntests=1e4;

disp('1) Pre-allocate, update vector in-place without creating new array.')
tic
for j = 1 : Ntests
   clear a
   a(100) = 0;
   a(1)=1;
   for i = 2:100
      a(3:end) = a(2:99);
      a(2) = i;
   end % i
end % j
toc

disp('2) Pre-allocate, copy & create new array by concatenation.')
tic
for j = 1 : Ntests
   clear a
   a(100) = 0;
   a(1)=1;
   for i = 2:100
      a = [ a(1) i a(2:end-1) ];
   end % i
end % j
toc

disp('3) No pre-allocation (current method).')
tic
for j = 1 : Ntests
   clear a
   a(1)=1;
   for i = 2:100
      a = [ a(1) i a(2:end) ];
   end % i
end % j
toc

结果是:

1) Pre-allocate, update vector in-place without creating new array.
Elapsed time is 2.359021 seconds.
2) Pre-allocate, copy & create new array by concatenation.
Elapsed time is 4.221047 seconds.
3) No pre-allocation (current method).
Elapsed time is 2.248106 seconds.

情况真的像这样令人沮丧,还是我可以对瓶颈做些什么呢?

Context of the problem:

每个双数组代表机器的时间线,双精度数是使用期间的开始时间 . 结束时间存储在另一个双数组中 . 对于每个使用期限,除了开始时间和结束时间之外还有其他字段 . 所以我有一些数组,每个字段一个 .

当我获得一段时间的新需求时,它是一个值集合的形式,每个字段一个,我必须看看它是否适合时间轴(我有其他逻辑来确定,我'我也在试图加速) . 如果它不合适,我会转到另一个时间轴再试一次 . 如果没有现有的时间表可以容纳新需求的开始到结束时间,我会创建另一台具有空白时间轴的计算机 .

假设一段使用时间由N个字段组成,其中开始和结束时间是这些字段中的两个 . 每个时间轴表示为N个数组,而不是N个字段的结构数组 . 这是因为经验测试和网上冲浪表明N个标量数组的操作速度比N个字段的单个结构数组更快 . 但是,如果我必须更新N个标量数组只是为了插入一个使用期限,这可能不再适用,我还没有测试过 . (我修改了使用数组字段从struct数组迁移到struct的代码,并且需要一些时间才能返回) .

上面的代码仅用于测试插入数组中间的开销 . 它并不意味着模拟此Context部分中描述的整个问题 .

请注意,我在下面的评论中同意这是一个优先级队列问题 . 这假设每个新的使用期已经由我的其他逻辑确定以适应时间线,然后将开始时间视为优先级 . 然而,经过反思,它并不是真正的完整优先级队列问题,因为直到最后我才真正从队列中取出任何东西 . 因此,它是简化使用优先级队列来构建时间轴 .

虽然我还没有为优先级队列选择和合并公开可用的Matlab代码,但我仍然有50%的信心确认会有净加速 . 这是因为在Matlab中调用函数的速度很慢,并且每个时间线在完全构建时平均包含不到六个使用期(至少对于当前的问题集) . 因此,与调用函数来更新优先级队列相比,简单插入很可能是构建时间轴的最快方式 . 当我有机会尝试时,我会更新这个问题 .