c – 擦除删除习语的性能增益来自何处
我需要从满足某个标准的向量中擦除所有元素.
我的第一种方法是遍历向量并在符合条件的所有元素上调用vector :: erase. 据我所知,vector :: erase对于这个用例有一个糟糕的性能,因为它从底层数组中删除了项目,并将向量的其余部分向前移动了一个元素(如果删除一系列元素则更多) ). remove算法将所有元素移除,并将它们移动到向量的末尾,因此您只需要移除向量的后部,这不涉及移位. 但为什么这比擦除更快? (它更快吗?) 不将元素移动到最后意味着像vector :: erase一样向前移动所有后续元素? 怎么来,删除只有O(n)的复杂性? 解决方法
这里的性能问题不是要删除要删除的元素,或者将它们移动到最后(实际上不会发生),而是关于移动要保留的元素.
如果对要删除的每个元素使用擦除,则需要在这些元素之后移动所有元素…对于每个要擦除的调用.通常,如果要删除k个元素,则将元素移动到最新的元素(在向量中)k次,而不是仅移动一次. 但是如果你调用remove,你只会移动一次(参见下面的例子). 一个小例子,可以更好地理解这两种方法的工作原理:
擦除作用于要移除的两个元素: >当你为第17个元素调用erase()时,你需要移动元素18到999,982个元素. 总的来说,你已经移动了962 982 = 1944个元素,其中962个被移动了两次,没有任何东西. 删除后,会发生以下情况: element 0 does not change; element 1 does not change; ... element 17 is "discarded"; element 18 is moved at position 17; element 19 is moved at position 18; ... element 36 is moved at position 35; element 37 is "discarded"; element 38 is moved at position 36; ... element 999 is moved at position 997. 总的来说,你已经移动了998个元素(1000减去你删除的两个元素),这比之前方法的1943个元素要好得多.如果要删除的元素超过2个,则更好. 您可以查看en.cppreference.com上的possible implementation以更好地了解std :: remove的工作原理. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |