【问题标题】:remove() method is too slowremove() 方法太慢
【发布时间】:2012-08-21 12:17:45
【问题描述】:

我在读取内存跟踪时遇到问题。我已阅读并在地图上保存了页面及其引用

地图结构:

    Map<Integer, List<Integer>> map = new HashMap<>();

然后我再次读取文件并从整数列表中删除引用

FileReader arq = new FileReader(new File(Path));
BufferedReader reader = new BufferedReader(arq, 41943040);
while ( (std = reader.readLine()) != null ) {
        requestedPage = Integer.parseInt(std, 16);
        //do something
        M.map.get(requestedPage).remove(0));
    }

问题是删除这些引用需要很长时间,而对于大的痕迹,删除这些引用需要几个小时。有人有其他解决方案吗?

谢谢!

【问题讨论】:

  • 你在使用List的什么实现?
  • 对不起,它是一个 ArrayList 实现
  • 谢谢,我恢复了LinkedList并从最后删除,现在只需4秒即可读取跟踪。

标签: java list map


【解决方案1】:

谢谢,我恢复了LinkedList并从最后删除,现在只需4秒即可读取跟踪。

编辑:从最后恢复和删除并没有改变结果,我犯了一个错误。只需使用 LinkedList 而不是 ArrayList 就解决了我的问题。

【讨论】:

    【解决方案2】:

    如果列表非常大,问题可能是从索引 1 到 size - 1 的所有元素都必须移动:从逻辑上讲,索引 n 处的项目被移动到索引 n-1。如果您查看the ArrayList source,您会看到有一个 System.arrayCopy 调用来执行此操作。您报告要执行的操作所花费的时间听起来像是存在更深层次的问题,但您可以尝试使用LinkedList 或重新设计您的算法,以便从列表末尾删除元素而不是正面。使用LinkedList,头元素被删除,其他节点都不需要修改。如果您坚持使用ArrayList,但每次都删除最后一个元素而不是第一个元素,则不需要arrayCopy。

    另外,看看Guava's Multimap。从逻辑上讲,它是 MapCollection 的值,就像你在这里一样,但它是一个更好的界面。 Guava 库中还有许多其他令人惊叹的类,如果您还没有使用它们,还应该检查一下!

    【讨论】:

    • 使用 LinkedList 没有任何区别(应该如此),我将尝试反转 List 顺序,然后按照您所说的从末尾删除。谢谢!
    • 抱歉,id 确实更改了时间。从 17 分钟到 10 分钟在我的踪迹上。不幸的是,我需要它更快。
    • 访问文件将比从LinkedList 中删除节点或从ArrayList 中删除最后一个元素要慢得多。您确定您看到的缓慢肯定是由于列表删除而不是文件访问造成的吗?另外,尝试在 BufferedReader 中尝试缓冲区的大小,或者根本不指定大小并使用默认大小。
    • 是的,我尝试输入 -1 而不是删除它,而且速度非常快,但是我每次访问地图时都需要测试它是否 == -1。
    • 随意接受并投票赞成建议颠倒列表并从末尾删除的答案(提示,提示)。但是如果你看一下line 169 in the source code for LinkedList,你会发现删除LinkedList 中的第一个元素应该非常快,所以我觉得发生了其他事情。也许 LinkedList 中节点的一些 GC 开销被如此快地创建和删除?
    【解决方案3】:

    我认为如果remove(0) 是您要在此列表上进行的唯一删除操作,LinkedList 是一个更好的数据结构:

    尝试:

    Map<Integer, LinkedList<Integer>> map = new HashMap<Integer, LinkedList<Integer>>();
    

    【讨论】:

    • 抱歉,id 确实更改了时间。从 17 分钟到 10 分钟在我的踪迹上。不幸的是,我需要它更快。但是谢谢你的提示! ;)
    • @FelipeCarminati 10 分钟移除 LinkedList 的头部?我很确定这种方法并不缓慢。列表中有多少个元素?
    • 我正在阅读大文件,一旦我从文件中读取页面引用,我就会转到地图中该页面的引用列表并删除第一个元素。对于我正在测试的跟踪,我将删除第一个元素 770 万次。 (对不起我的英语)。
    • @FelipeCarminati - 删除链表的第一个元素 770 万次只需要几分之一秒......无论列表的长度如何。这不是代码中的瓶颈所在。我建议您对此保持科学态度。分析您的代码。
    • @FelipeCarminati 确保您使用旁边的勾号将最能帮助您的答案标记为“已接受”。这样,面临同样问题的人会很快看到解决方案。
    猜你喜欢
    • 1970-01-01
    • 2018-08-01
    • 1970-01-01
    • 2012-07-17
    • 1970-01-01
    • 1970-01-01
    • 2018-10-16
    • 1970-01-01
    • 2013-05-27
    相关资源
    最近更新 更多