C ++:我可以重用/移动std :: list元素到中间吗?

时间:2018-07-08 22:17:36

标签: c++ memory iterator micro-optimization stdlist

我正在优化我的LRU缓存实现的常量因子,在这里我使用std::unordered_map::iterator存储到std::list,即使附近的元素被保存,也保证它们仍然有效。添加或删除。这样会导致O(n)运行时,所以,我要考虑常量因素。

我知道每个迭代器基本上都是指向保存我的东西的结构的指针。当前,要将给定元素移到链表的末尾,我使用迭代器调用l.erase(it),然后将新对w / make_pair(key, value)分配给l.push_back()或{{1} }(不太确定两者之间的区别),然后使用prev(l.end()) or --l.end()将新的迭代器放回地图中。

是否有一种方法可以重用它所指向的现有迭代器和基础的双向链接列表结构,而不必每次都按照上面的方法销毁它?

(我的运行时当前为56ms(跳动率为99.78%),但是在leetcode上最好的C ++提交是50ms。)

1 个答案:

答案 0 :(得分:1)

HolyBlackCat指出,解决方案是使用std::list::splice

l.splice(l.end(), l, it);

这避免了需要l.erasemake_pair()l.push_back / l.emplace_back(),也不需要获取prev(l.end()) / --l.end()来更新基础std::map

遗憾的是,它并不能提高运行速度,但是,哦,好吧,那么可能是度量的变化,或者是使用更专门的数据结构的实现。

更新:实际上,我修复了重用l.begin()中“已删除”元素的最终实例,并得到了52ms / 100%! :-)