nedtries的作者是什么意思“就地”?

时间:2011-01-14 14:29:50

标签: c binary-tree bit-manipulation trie patricia-trie


I.刚刚实现了一种按位trie(基于nedtries),但我的代码做了很多 内存分配(对于每个节点)。  与我的实施相反,在其他事物中,nedtries声称速度很快, 因为它们的内存分配数量很少(如果有的话)。 作者声称他的实施是“就地”的,但在这种情况下它的真正含义是什么? nedtries如何实现如此少量的动态内存分配?

Ps:我知道这些来源是可用的,但代码很难遵循,我无法弄清楚它是如何工作的

4 个答案:

答案 0 :(得分:10)

我是作者,所以这是为了谷歌的许多人的利益,他们同样在使用nedtries方面遇到困难。我要感谢这里的人们在stackflow上没有对我个人做出令人不快的评论,其他一些关于nedtries的讨论也是如此。

  1. 恐怕我不明白知道如何使用它的困难。使用非常简单 - 只需复制Readme.html文件中的示例:
  2. typedef struct foo_s foo_t;
    struct foo_s {
      NEDTRIE_ENTRY(foo_t) link;
      size_t key;
    };
    typedef struct foo_tree_s foo_tree_t;
    NEDTRIE_HEAD(foo_tree_s, foo_t);
    static foo_tree_t footree;

    static size_t fookeyfunct(const foo_t *RESTRICT r) { return r->key; }

    NEDTRIE_GENERATE(static, foo_tree_s, foo_s, link, fookeyfunct, NEDTRIE_NOBBLEZEROS(foo_tree_s));

    int main(void) { foo_t a, b, c, *r; NEDTRIE_INIT(&footree); a.key=2; NEDTRIE_INSERT(foo_tree_s, &footree, &a); b.key=6; NEDTRIE_INSERT(foo_tree_s, &footree, &b); r=NEDTRIE_FIND(foo_tree_s, &footree, &b); assert(r==&b); c.key=5; r=NEDTRIE_NFIND(foo_tree_s, &footree, &c); assert(r==&b); /* NFIND finds next largest. Invert the key function to invert this */ NEDTRIE_REMOVE(foo_tree_s, &footree, &a); NEDTRIE_FOREACH(r, foo_tree_s, &footree) { printf("%p, %u\n", r, r->key); } NEDTRIE_PREV(foo_tree_s, &footree, &a); return 0; }

    你声明你的项目类型 - 这里是struct foo_s。你需要内部的NEDTRIE_ENTRY(),否则它可以包含你喜欢的任何东西。您还需要一个密钥生成功能。除此之外,它是漂亮的样板。

    我自己也不会选择这种基于宏的初始化系统!但它是为了与BSD rbtree.h兼容,所以使用BSD rbtree.h很容易交换到任何东西。

    1. 关于我对“就地”的使用 算法,我想我的缺乏 计算机科学培训表明 这里。我称之为“到位” 是你只使用记忆的时候 传入一段代码,如果 你把64个字节移到了原地 算法它只会触及64 字节即它不会使用 额外的元数据,或分配一些 额外的记忆,或者确实写到 全球国家。一个很好的例子是 “就地”排序实施在哪里 只有正在排序的集合 (我想是线程堆栈) 感动了。

      因此没有,nedtries不需要 内存分配器。它存储了所有 它在NEDTRIE_ENTRY中需要的数据 和NEDTRIE_HEAD宏扩展。 换句话说,当你分配 你的struct foo_s,你做的都是 nedtries的内存分配。

    2. 关于理解“宏观 善良“,它更容易 如果编译就能理解逻辑 它作为C ++然后调试它:)。该 C ++ build使用模板和 调试器会干净地显示状态 在任何给定的时间。事实上,所有 我的调试发生在一个 C ++构建和我一丝不苟 将C ++更改转录为 macroised C。

    3. 最后,在新发布之前,我 搜索谷歌的人 我的软件问题,看看是否 我可以解决问题而且通常都是 惊讶于别人的评价 我和我的免费软件。首先, 为什么没有那些人 困难直接问我 救命?如果我知道有 那么,文档出了问题 我可以解决它们 - 同样,请问 stackoverflow不让我知道 马上就有了一个文档 问题bur相当依赖我 找到下一个版本。所以我会 说是如果有人发现了 我的文档有问题,请做 给我发电子邮件并说出来,即使在那里 是一个像这里一样的讨论 stackflow。

    4. 尼尔

答案 1 :(得分:4)

就地表示您对原始(输入)数据进行操作,因此输入数据成为输出数据。 非就地表示您具有单独的输入和输出数据,并且不会修改输入数据。 就地操作具有许多优点 - 较小的缓存/内存占用,较低的内存带宽,因此通常具有更好的性能等,但它们具有破坏性的缺点,即您丢失了原始输入数据(可能或可能不重要,取决于用例)。

答案 2 :(得分:4)

我看了一下nedtrie.h源代码。 它似乎是“就地”的原因是必须将trie簿记数据添加到您要存储的项目中。

您使用NEDTRIE_ENTRY宏将父/子/下一个/上一个链接添加到您的数据结构,然后您可以将该数据结构传递给各种trie例程,这些例程将提取并使用这些添加的成员。

所以它是“就地”的,因为你增加了现有的数据结构和trie代码搭载它。

至少这就是它的样子。该代码中有很多宏观优点,所以我可能会让自己感到困惑(:

答案 3 :(得分:-1)

就地意味着对输入数据进行操作并(可能)更新它。这意味着没有复制和/或移动输入数据。这可能会导致丢失输入数据原始值,如果它与您的特定情况相关,则需要考虑这些值。