当前位置 : 主页 > 网络安全 > 测试自动化 >

性能 – 优化插入列表中间

来源:互联网 收集:自由互联 发布时间:2021-06-22
我有 algorithms适用于动态增长的列表(连续的内存,如C矢量,Java ArrayList或C#List).直到最近,这些算法才会在列表中间插入新值.当然,这通常是一个非常缓慢的操作.每次添加项目时,需要将其后
我有 algorithms适用于动态增长的列表(连续的内存,如C矢量,Java ArrayList或C#List).直到最近,这些算法才会在列表中间插入新值.当然,这通常是一个非常缓慢的操作.每次添加项目时,需要将其后的所有项目转移到更高的索引.对每种算法执行此操作几次,事情变得非常缓慢.

我的意识是我可以将新项添加到列表的末尾,然后将它们旋转到位.这是一个选择!

另一种选择,当我知道我提前添加了多少项时,就是在后面添加许多项目,移动现有项目,然后在我为自己制作的洞中就地执行算法.否定的是我必须在列表的末尾添加一些默认值,然后才覆盖它们.

我对这些选项进行了快速分析,并得出结论,第二种选择更有效.我的理由是,使用第一个选项的轮换将导致就地交换(需要临时).我唯一担心的第二个选项是我创建了一堆默认值,这些默认值会被丢弃.大多数情况下,这些默认值将为null或mem-filled值类型.

但是,我希望有其他熟悉算法的人告诉我哪种方法会更快.或者,也许我没有考虑过更有效的解决方案.

对于除阵列末尾之外的任何位置的大量插入或删除,数组效率不高.考虑使用不同的数据结构(例如在其他答案之一中建议的数据结构)是否可能更有效.在不知道你想要解决的问题的情况下,几乎不可能建议数据结构(对于所有问题都没有一个解决方案).话虽如此…

第二种选择绝对是两者的更好选择.一个更好的选择(避免默认值问题):简单地将789复制到最后并用456覆盖中间789.因此唯一的中间步骤是0123789789.

但是,您的默认值问题(通常)不是一个大问题:

>在Java中,对于一个,你不能(据我所知)为不是0或空填充的数组分配内存. C STL容器也强制执行这个我相信(但不是C本身).
>与任何中等大小的类相比,指针的大小是最小的(因此将其分配给默认值也花费最少的时间)(在Java和C#中,一切都是指针,在C中你可以使用指针(类似于boost :: shared_ptr)或指针向量优先于直指针)(N / A到基元,它们起始很小,因此通常也不是一个大问题).

我还建议在开始插入数组末尾之前强制重新分配到指定的大小(Java的ArrayList :: ensureCapacity或C的vector :: reserve).如果您不知道 – 变长度数组实现往往有一个比size()返回的内部数组大或可访问的内部数组(为了防止在插入或删除值时不断重新分配内存).

另请注意,复制部分数组比使用for循环手动执行更有效的方法(例如Java的System.arraycopy).

网友评论