Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
c+中的持久数据结构+; 是否存在类似C++中的持久性数据结构实现?类似于Culjure/< P>如果我正确地理解问题,你所寻求的是复制对象的能力,而不需要在复制时实际支付,仅当需要时才复制。可以在不损坏另一个对象的情况下更改其中一个对象。 这被称为“书面复制” 如果这是您正在寻找的,这可以很容易地在C++中使用共享指针实现(参见Boost,SyrdYPPTR,作为一个实现)。 最初,副本将与源共享所有内容,但一旦进行了更改,对象共享指针的相关部分将替换为指向新创建的深度复制对象的其他共享指针。 (我意识到这个解释是模糊的——如果这确实是你的意思,那么答案可以详细说明)。_C++_Clojure_Persistence_Immutability - Fatal编程技术网

c+中的持久数据结构+; 是否存在类似C++中的持久性数据结构实现?类似于Culjure/< P>如果我正确地理解问题,你所寻求的是复制对象的能力,而不需要在复制时实际支付,仅当需要时才复制。可以在不损坏另一个对象的情况下更改其中一个对象。 这被称为“书面复制” 如果这是您正在寻找的,这可以很容易地在C++中使用共享指针实现(参见Boost,SyrdYPPTR,作为一个实现)。 最初,副本将与源共享所有内容,但一旦进行了更改,对象共享指针的相关部分将替换为指向新创建的深度复制对象的其他共享指针。 (我意识到这个解释是模糊的——如果这确实是你的意思,那么答案可以详细说明)。

c+中的持久数据结构+; 是否存在类似C++中的持久性数据结构实现?类似于Culjure/< P>如果我正确地理解问题,你所寻求的是复制对象的能力,而不需要在复制时实际支付,仅当需要时才复制。可以在不损坏另一个对象的情况下更改其中一个对象。 这被称为“书面复制” 如果这是您正在寻找的,这可以很容易地在C++中使用共享指针实现(参见Boost,SyrdYPPTR,作为一个实现)。 最初,副本将与源共享所有内容,但一旦进行了更改,对象共享指针的相关部分将替换为指向新创建的深度复制对象的其他共享指针。 (我意识到这个解释是模糊的——如果这确实是你的意思,那么答案可以详细说明)。,c++,clojure,persistence,immutability,C++,Clojure,Persistence,Immutability,获得持久数据结构的主要困难确实是缺少垃圾收集 如果没有合适的垃圾收集方案,那么可能会得到一个糟糕的方案(即引用计数),但这意味着您需要格外小心,不要创建循环引用 它改变了结构的核心。例如,想想二叉树。如果创建节点的新版本,则需要其父节点的新版本才能访问它(等等)。现在,如果关系是双向的(子-父),那么实际上您将复制整个结构。这意味着您将有一个父->子关系,或者相反的关系(不太常见) 我可以考虑实现二叉树或B-树。例如,我几乎看不到如何获得正确的数组 另一方面,我同意在多线程环境中拥有高效的应用程

获得持久数据结构的主要困难确实是缺少垃圾收集

如果没有合适的垃圾收集方案,那么可能会得到一个糟糕的方案(即引用计数),但这意味着您需要格外小心,不要创建循环引用

它改变了结构的核心。例如,想想二叉树。如果创建节点的新版本,则需要其父节点的新版本才能访问它(等等)。现在,如果关系是双向的(子-父),那么实际上您将复制整个结构。这意味着您将有一个父->子关系,或者相反的关系(不太常见)

我可以考虑实现二叉树或B-树。例如,我几乎看不到如何获得正确的数组


另一方面,我同意在多线程环境中拥有高效的应用程序将是一件好事。

我也推出了自己的应用程序,但有一个相当全面的示例,它是受clojure特别启发的。几年前,我听了约翰·卡马克(John Carmack)的一次演讲,当时他正全神贯注于函数式编程潮流,这让我兴奋不已。他似乎能够想象一个围绕不变的数据结构旋转的游戏引擎。虽然他没有进入细节,虽然这在他的头脑中似乎是一个模糊的想法,但事实上,他正在认真考虑,似乎不认为开销会急剧降低帧速率,这足以让我对探索这个想法感到兴奋

实际上,我使用它作为一个优化细节,这可能看起来很矛盾(不变性有开销),但我的意思是在特定的上下文中。如果我绝对想这样做:

// We only need to change a small part of this huge data structure.
HugeDataStructure transform(HugeDataStructure input);
。。。我绝对不想让这个函数产生副作用,这样它就可以是线程安全的,而且永远不会被滥用,那么我别无选择,只能复制这个巨大的数据结构(可能跨越一个千兆字节)

在这种情况下,我发现拥有一个小型的不可变数据结构库非常有帮助,因为它通过简单的复制和引用未更改的部分,使上述场景相对便宜。也就是说,我主要使用一个不变的数据结构,基本上是一个随机访问序列,如下所示:

Immutable transform(Immutable input)
{
    Transient transient(input);

    // make changes to mutable transient.
    ...

    // Commit the changes to get a new immutable
    // (this does not touch the input).
    return transient.commit();
}

正如其他人所提到的,它确实需要一些谨慎、调整、全面的测试和许多VTune会话,以使其线程安全和高效,但在我添加了肘部润滑脂之后,它确实使事情变得非常简单

在自动线程安全的基础上,每当我们使用这些结构来编写没有副作用的函数时,您还可以获得诸如非破坏性编辑、琐碎的撤销系统、琐碎的异常安全(无需通过函数中的作用域保护回滚副作用,因为在异常路径中不会导致任何副作用),并允许用户复制和粘贴数据并对其进行实例验证,而无需占用大量内存,直到/除非他们修改粘贴内容作为奖励。实际上,我发现这些奖金在日常生活中比线程安全性更有用

我使用“瞬态”(也称为“构建器”)来表示数据结构的更改,如下所示:

Immutable transform(Immutable input)
{
    Transient transient(input);

    // make changes to mutable transient.
    ...

    // Commit the changes to get a new immutable
    // (this does not touch the input).
    return transient.commit();
}
我甚至有一个不可变的图像库,用于图像编辑,以简化非破坏性编辑。它使用与上述结构类似的策略,将图像视为瓷砖,如下所示:

当一个瞬态被修改,我们得到一个新的不可变项时,只有被修改的部分是唯一的。其余的分幅是浅复制的(仅32位索引):

我确实在一些性能相当关键的领域使用了它们,比如网格和视频处理。对于每个块应该存储多少数据,进行了一些微调(太多,我们浪费处理和内存深度复制太多数据,太少,我们浪费处理和内存浅复制太多具有更频繁线程锁的指针)


我不会将其用于光线跟踪,因为这是可以想象到的最极端的性能关键领域之一,用户可以注意到最小的开销(他们实际上会进行基准测试并注意到2%范围内的性能差异),但大多数情况下,它们足够有效,当您可以将这些巨大的数据结构作为一个整体左右复制以简化线程安全、撤消系统、无损编辑等,而不必担心内存使用爆炸性增长和深度复制所花费的明显延迟时,这是一个非常了不起的好处。

C++不会被垃圾收集,这使得建造这样的建筑极其复杂。如果你不在乎内存泄漏(或者集成了垃圾收集器),那就很容易了。哇,冷静点,兄弟。查找“Clojure”并不是那么困难;我通常不会吹嘘自己没有听说过一种处于函数式编程前沿的语言。我不是它的超级粉丝,但我觉得奇怪的是,一个问题竟然因为提到它而被贬低。(尽管我衷心同意你的建议,重新评估需求,而不是鞋匠