Scala(或Java)中保持插入顺序的自适应映射

Scala(或Java)中保持插入顺序的自适应映射,java,scala,collections,Java,Scala,Collections,我希望找到并重用(如果可能)具有以下属性的映射实现: 虽然条目的数量很小,比如object map)。作为参考,我注意到OP没有发现我的解决方案令人满意,并要求我删除它。简言之,我们的想法是将所有内容都放在索引数组中,采用Fortran风格,然后围绕这个结构编写漂亮的包装,这样处理起来就很愉快了。这种方法的优点是速度非常快(主要是因为只使用原语),并且自然地保留了插入顺序(因为当需要新条目时,只需向索引中添加1)。Fortran和C中的许多图形工作都是这样做的,但我同意我没有确定所需的映射。既然

我希望找到并重用(如果可能)具有以下属性的映射实现:


  • 虽然条目的数量很小,比如<32,但底层存储应该在这样的阵列中完成[key0,val0,key1,val1,…]此存储方案避免了许多小条目对象,并提供了极快的查找(即使它们是顺序扫描!)在现代CPU上,由于CPU的缓存没有失效,并且缺少指向堆的指针间接寻址

  • 映射应保持键/值对的插入顺序,而不考虑与LinkedHashMap类似的条目数

  • 我们正在开发一个巨大(数百万个节点/边)的内存表示Scala中的图形和这样的映射将允许我们以更高效的方式存储节点/边属性以及每个节点的边,用于99%以上的节点和边,这些节点和边几乎没有属性或邻居,同时保留属性和边的按时间顺序插入顺序

    如果有人知道Scala或Java映射具有这样的特性,我将不胜感激


    Thanx

    在java下,您可以维护2d数组(电子表格)。我写了一个程序,它基本上定义了一个二维数组,其中包含3列数据,3列用于查找数据。这三个列是testID、SubtestID和Mode。这使我基本上可以通过testid和mode或任何组合来查找值,也可以通过静态放置来引用。该表在启动时加载到内存中,并由程序引用。它可以无限扩展,并且可以根据需要添加新值

    如果你感兴趣,今晚我可以发布一个源代码示例


    另一个想法可能是在程序中维护数据库。数据库设计用于组织大量数据。

    虽然我不知道有任何实现完全符合您的要求,但您可能有兴趣浏览雅加达公共图书馆中的()

    不幸的是,Jakarta库已经过时了(例如,最新的稳定版本中不支持泛型,尽管它很有希望在主干中看到这一点正在发生变化),我通常更喜欢,但您可能值得花时间看看Apache是如何实现的


    不幸的是,Flat3Map并没有保留键的顺序,但我确实对你原来的帖子有一个建议。我建议使用并行数组,而不是像
    [key0,val0,key1,val1,…];也就是说,一个数组具有
    [key0,key1,…]
    ,另一个数组具有
    [val0,val1,…]
    。通常我不是并行数组的支持者,但至少通过这种方式,您可以拥有一个K类型的数组,即键类型,以及另一个V类型的数组,即值类型。在Java级别,这有它自己的缺点,因为您不能使用语法
    K[]keys=newk[32]
    ;相反,您需要使用。如果LinkedHashMap对您来说太慢,您是否使用profiler进行过测量?也许你不需要新的地图-过早的优化是万恶之源。。
    无论如何,对于在一秒钟内处理数百万条或更多数据而言,即使是最佳优化的映射也可能太慢,因为在这种情况下,每个方法调用都会降低性能。然后,您所能做的就是将算法从Java集合重写为数组(即int->object map)。

    作为参考,我注意到OP没有发现我的解决方案令人满意,并要求我删除它。简言之,我们的想法是将所有内容都放在索引数组中,采用Fortran风格,然后围绕这个结构编写漂亮的包装,这样处理起来就很愉快了。这种方法的优点是速度非常快(主要是因为只使用原语),并且自然地保留了插入顺序(因为当需要新条目时,只需向索引中添加1)。Fortran和C中的许多图形工作都是这样做的,但我同意我没有确定所需的映射。既然您已经在考虑实现,为什么不自己编写呢?围绕数组或LinkedHashMap编写包装器不会那么困难。您将集合用于特殊情况。因此,你不应该为这种正常的储蓄方式而烦恼。创建您自己的datastrukture以获得更高的性能是很有趣的。您可以针对您的案例优化您的结构,因为您似乎非常了解您的图表。因此,您应该考虑树、列表等,以获得尽可能高的性能。可能您的运行性能为O(n*logn)或更低……)最后,我将编写自己的自适应映射实现(当然是Scala)。但我(也许是天真地)认为,在实践中,如果有人现在已经解决了这个问题,那么拥有多个映射(其中只有少数映射具有多个条目)的模式就会经常出现:-)“虽然条目的数量很小,比如说<32,但底层存储应该在这样的数组中完成[key0,val0,key1,val1,…”这个答案并没有解决我关于自适应地图的狭隘问题。我们确实考虑了其他图形表示,但是由于许多技术上的原因,我不能进入,我们必须保持一个“本地化”的设计,其中图形节点,边缘等(所有的原子真的)必须有自己的属性映射对象。同样,我希望避免一种常见的模式,即为小型(<32个条目映射)创建许多微小的Map.Entry类对象,以节省内存并保持CPU缓存位置(即,实际上扫描小型数组总是比跟踪堆指针链更快)。现在,这是我一直在寻找的一种答案。在我以前的工作中,我发现只有在32个甚至64个条目之后,“平面”映射(apache ppl称之为平面)才会比标准哈希映射慢,这可能是因为现代CPU具有非常好的内核缓存和指向堆的指针间接寻址导致内存暂停。理想情况下