【问题标题】:Which container should I use?我应该使用哪个容器?
【发布时间】:2012-04-14 16:39:15
【问题描述】:

我是 haskell 的新手,所以我正在尝试在 haskell 中重新创建以下 C++ 代码。

int main() {
    class MyClass {
        public:
        int a;
        std::string s;
        float f;
    };
    std::vector <MyClass> v;
    LoadSerialized(&v); // don't need haskell equivalent; just reads a bunch of MyClass's and pushes them back onto v
}

现在,我查看了 haskell 中可能用作 std::vector 的各种容器:有列表、未装箱的向量、装箱的向量,以及一些奇怪的外来指针用法,如下所示:

data Table = Table { floats :: ForeignPtr CFloat
                   , ints   :: ForeignPtr Int    }

newTable :: IO Table
newTable = do
    fp <- S.mallocByteString (floatSize * sizeOf (undefined :: CFloat))
    ip <- S.mallocByteString (intSize   * sizeOf (undefined :: Int   ))
    withForeignPtr fp $ \p ->
        forM_ [0..floatSize-1] $ \n ->
            pokeElemOff p n pi
    withForeignPtr ip $ \p ->
        forM_ [0..intSize-1]   $ \n ->
            pokeElemOff p n n
    return (Table fp ip)

现在,我可以用我认为最好的方式来实现 C++ 代码——成为一个 Haskell 新手。或者我可以问那些对语言更有经验的人最好的方法是什么,因为对我来说,这里似乎有一些我错过了的细微差别。简单地说,我想将一个包含许多数据类型的结构推送到一个 haskell 容器中,我不关心顺序。如果有帮助,我会将序列化数据读入容器中,正如您在 LoadSerialized 中看到的那样。

我没有混入 C++ 代码。

(编辑:stackoverflow 政策是否允许通过编辑(不是次要)审查问题?它确实说“始终尊重原作者。”)

【问题讨论】:

  • n.b.编辑从问题中删除不必要的粗鲁是系统的意图,是的。 StackOverflow 是人们提出和回答编程问题的地方,它不是爆发脾气暴躁的争论的地方。
  • 粗鲁?怎么这么粗鲁?这正是为什么我不必要地重写了在这个问题之前发布的问题。
  • ehird,你拿出的比我投入的要多(语气是事实),但好吧,我被否决了。

标签: haskell


【解决方案1】:

如果你是在 Haskell 中编写整个程序, 除非你有充分的理由不这样做,否则只需使用一个列表。 (如果您确实有充分的理由不这样做,请说出它是什么,我们可以帮助您选择更合适的数据结构。例如,对特定列表元素的随机访问是 O(n) 而不是 O(1) C++ 向量,在 Haskell 中更新数据结构中的值是不同的。)

如果你在同一个程序中混合使用 Haskell 和 C++,并且需要帮助从 Haskell 调用 C++,请说。

  • 默认使用列表。编译器可以将 map、foldr 和 filter 等列表操作融合在一起,从而生成比使用 C++ 向量通常更高效的代码。
  • 如果您发现自己需要按索引查找元素,或者想要改变特定索引处的元素,请使用某种数组。请参阅Data.Array、Data.Array.IO 和 Data.Array.ST。
  • 如果您发现自己需要在数据结构的中间或结构的两端插入新元素,请使用序列。见Data.Sequence。

【讨论】:

  • 不在 C++ 中混合。我认为 list 在这里可能不是一个好主意的原因是显然存在性能问题。此外,我认为可能与 C++ 有相似之处,因为您只是不使用某些容器来解决某些问题:例如,即使 std::list 有效,也很少使用 std::list 代替 std::vector 。显然,对于haskell 中的这个问题,haskell 向量容器比列表更高效?但为什么要推荐它们呢?
  • 甚至没有听说过 Data.Array 或 Sequence。希望所有haskell数据结构都有一个复杂度表。最后一件事,我应该使用 Data.Vector 做什么?而且我假设只有在混合 C++ 代码时才应该使用外部指针方法?
  • @user175492:像这样的低级代码是 Haskell 中的最后手段,用于那些你确实需要挤出最后一滴性能的情况。在大多数情况下,高级接口足够快,同时使用起来非常简单。
  • @user175492:使用外部指针(或等效的 Data.Vector.Unboxed)比其他方法更节省空间,但可能会或可能不会更快,具体取决于哪个方法您使用的操作。它也不太方便,因为您需要定义一个 Storable 实例(或 Unbox for Data.Vector.Unboxed)。
  • @dave4420 Data.Vector 是Data.Array 的一个更高效的版本,其 API 并不可怕。我会在任何一天都推荐它而不是 arrays,即使它不附带 GHC。
猜你喜欢
  • 2012-11-23
  • 2018-12-03
  • 2010-11-18
  • 1970-01-01
  • 2010-11-10
  • 1970-01-01
  • 1970-01-01
  • 2016-09-28
  • 2015-12-05
相关资源
最近更新 更多