我正在优化lru缓存实现的常数因子,在这里我使用 std::unordered_map 储存 ::iterator S至 std::list ,即使添加或删除了附近的元素,也保证这些元素仍然有效。这会导致O(N)运行时,所以,我要寻找常数因子。
std::unordered_map
::iterator
std::list
我知道每个迭代器基本上都是指向保存我的东西的结构的指针。当前,要将给定元素移到链接列表的后面,我调用 l.erase(it) 使用迭代器,然后分配一个新的对w/ make_pair(key, value) 到 l.push_back() 或 l.emplace_back() (不太确定两者之间的区别),然后将新的迭代器重新插入到map w中/ prev(l.end()) or --l.end() 是的。
l.erase(it)
make_pair(key, value)
l.push_back()
l.emplace_back()
prev(l.end())
--l.end()
是否有办法重用现有的迭代器和它指向的底层双链表结构,而不是像上面那样每次都要销毁它?
(我的运行时间目前是56ms(节拍99.78%),但是最好的C++代码是50ms。
正如 HolyBlackCat ,解决方案是使用 std::list::splice 是的。
std::list::splice
l.splice(l.end(), l, it);
这样可以避免 l.erase ,请 make_pair() 我是说, l.push_back / l.emplace_back() ,以及获取 prev(l.end()) / --l.end() 更新底层 std::map 是的。
l.erase
make_pair()
l.push_back
std::map
不过,不幸的是,它并没有带来更好的运行速度,但是,哦,好吧,可能是一个度量变化,或者是一个使用更专业的数据结构的实现。
更新:实际上,我修复了重用 l.begin() ,得到52ms/100%!:-)
l.begin()