erlang 是否以任何巧妙的方式实现记录复制和修改?

2023-12-23

given:

-record(foo, {a, b, c}).

我做了这样的事情:

Thing = #foo{a={1,2}, b={3,4}, c={5,6}},
Thing1 = Thing#foo{a={7,8}}.

从语义角度来看,Thing 和 Thing1 是唯一的实体。然而,从语言实现的角度来看,制作 Thing 的完整副本来生成 Thing1 会非常浪费。例如,如果记录大小为一兆字节,并且我制作了一千个“副本”,每个副本修改了几个字节,那么我就烧毁了一个千兆字节。如果内部结构跟踪父结构的表示,并且每个派生结构以指示其自己的更改但保留其他人的版本的方式标记该父结构,则可以以最小的内存开销创建派生结构。

我的问题是这样的:erlang 是否在内部做了一些聪明的事情来保持通常的 erlang 乱写的开销?

Thing = #ridiculously_large_record,
Thing1 = make_modified_copy(Thing),
Thing2 = make_modified_copy(Thing1),
Thing3 = make_modified_copy(Thing2),
Thing4 = make_modified_copy(Thing3),
Thing5 = make_modified_copy(Thing4)

……最小化?

我之所以这么问,是因为如果是这种情况,我进行跨进程通信的方式将会发生很多变化。


垃圾收集和内存分配的确切工作原理只有少数人知道。值得庆幸的是,他们非常乐意分享他们的知识,以下内容基于我从 erlang-questions 邮件列表以及与 OTP 开发人员讨论中学到的知识。

当在进程之间发送消息时,内容总是被复制,因为进程之间没有共享堆。唯一的例外是大于 64 字节的二进制文件,其中仅复制引用。

在一个进程中执行代码时,仅更新部分内容。让我们分析元组,因为这是您提供的示例。

元组实际上是一种结构,它将对实际数据的引用保留在堆上的某个位置(小整数除外,也许还有一种我不记得的数据类型)。当您更新元组时,例如使用setelement/3,创建一个新元组并替换给定元素,但是对于所有其他元素,仅复制引用。有一个例外 http://www.erlang.org/doc/efficiency_guide/commoncaveats.html#id62422我一直无法利用这一点。

垃圾收集器跟踪每个元组并了解何时可以安全地回收不再使用的任何元组。元组引用的数据可能仍在使用中,在这种情况下,不会收集数据本身。

一如既往,Erlang 为您提供了一些工具来准确了解正在发生的事情。效率指南 http://www.erlang.org/doc/efficiency_guide/processes.html#id67714详细说明如何使用erts_debug:size/1 and erts_debug:flat_size/1了解在进程内部使用和复制时数据结构的大小。跟踪工具还可以让您了解垃圾收集的时间、内容和数量。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

erlang 是否以任何巧妙的方式实现记录复制和修改? 的相关文章

  • Java中如何高效存储小字节数组?

    By small字节数组 我指的是长度从 10 到 30 的字节数组 By store我的意思是存储它们在内存中 不序列化并持久化到文件系统 系统 macOS 10 12 6 Oracle jdk1 8 0 141 64 位 JVM 参数
  • 在浏览器上录制视频并上传到LAMP服务器

    我已经尝试了很多东西 red5 jquery 网络摄像头 html5 但这些解决方案都没有录制视频并准备好上传到服务器 无论如何 html5 flash 等等 更好的跨浏览器解决方案 最好的 上传视频 音频 并将结果上传到服务器 我猜是通过
  • C++11 内部 std::string 表示形式 (libstdc++)

    std string 在 c 11 libstdc 中如何内部表示 在深入研究实现时 我发现 A string looks like this Rep M length basic string
  • git 索引到底包含什么?

    Git 索引到底包含哪些内容 可以使用什么命令查看索引内容 感谢您的所有回答 我知道索引充当暂存区 提交的内容是在索引中而不是工作树中 我只是好奇索引对象由什么组成 我猜它可能是文件名 目录名 SHA 1 对的列表 也许是一种虚拟树 在 G
  • 清除通过在 IPython 中绘图分配的内存

    我正在 IPython QtConsole 和 Notebook 中绘制一些大图 这些占用了大量的内存 但是一旦它们被绘制出来 我就不再需要它们了 它们就可以走了 我怎样才能释放内存 None以下作品 close clf cla reset
  • 我要恢复我的记忆!我怎样才能真正处理一个控件?

    我正在制作一个应用程序 它创建大量的窗口控件 按钮和标签等 它们都是通过函数动态生成的 我遇到的问题是 当我删除控件并处置它们时 它们不会从内存中删除 void loadALoadOfStuff while tabControlToClea
  • 在 4.x 内核上的 64 位内存中查找系统调用表

    我正在尝试编写一个简单的内核模块来查找 Linux 中的 sys call table 但遇到了一些麻烦 我在这里找到了 32 位 Linux 的基本指南 https memset wordpress com 2011 03 18 sysc
  • 在 Erlang 中是否有一种惯用的方法来对函数参数进行排序?

    似乎列表模块中的不一致 例如 split 将数字作为第一个参数 将列表作为第二个参数 而 sublists 将列表作为第一个参数 将 len 作为第二个参数 好的 讲一下我记得的一些历史以及我的风格背后的一些原则 正如克里斯蒂安所说 图书馆
  • 为什么要在堆而不是堆栈上分配内存? [复制]

    这个问题在这里已经有答案了 可能的重复 什么时候最好使用堆栈而不是堆 反之亦然 https stackoverflow com questions 102009 when is it best to use a stack instead
  • tcmalloc/jemalloc 和内存池之间有什么区别(以及选择的理由)?

    tcmalloc jemalloc是改进的内存分配器 还引入了内存池以更好地分配内存 那么它们之间有什么区别以及在我的应用中如何选择它们呢 这取决于您的程序的要求 如果您的程序有更多的动态内存分配 那么您 需要从可用的分配器中选择一个内存分
  • 在Erlang中,是否可以将正在运行的进程发送到不同的节点?

    我一直在研究移动代理 并且想知道是否可以将正在运行的进程发送到 erlang 中的另一个节点 我知道可以向另一个节点上的进程发送消息 我知道可以在集群中的所有节点上加载模块 是否可以将特定节点上可能处于某种状态的进程移动到另一个节点并恢复其
  • C# 记录类型:记录子类之间的相等比较

    给定父记录类型 public record Foo string Value 和两个记录子类Bar and Bee我想知道是否可以实施Equals在基类中 因此 Foo Bar 或 Bee 的实例都被考虑equal基于Value 两者都与E
  • 无法启动使用 rebar 生成的示例 erlang 版本

    一般来说 我是 rebar 和 erlang 的初学者 我试图根据本教程使用 rebar 创建一个 erlang 版本 http www metabrew com article erlang rebar tutorial generate
  • 找出Linux上一个进程使用了​​多少内存页

    我需要找出进程分配了多少内存页 每个页面是 4096 进程内存使用情况我在查找正确值时遇到一些问题 当我查看 gome system monitor 时 内存映射下有几个值可供选择 Thanks 这样做的目的是将内存使用量除以页数并验证页大
  • 以编程方式获取 Android 设备的所有 RAM 内存,而不仅仅是分配给用户进程的内存

    我有一台设备 我确信它的 RAM 内存为 512 MB 希望能够以编程方式检索该值 512 MB 到目前为止 我在互联网上遇到的主要是这两种方式 https stackoverflow com a 16143065 1521264 http
  • 如何在 gen_servers 中进行选择性接收?

    我将大部分应用程序移植到 OTP 行为 但我陷入困境 我不知道如何使用 gen server 进行选择性接收 如果没有任何回调函数子句与消息匹配 则不会将消息放回邮箱 而是会出错 现在 无论我走到哪里 人们都称赞选择性接收 无论我走到哪里
  • 如何在 C++ 中急于提交分配的内存?

    总体情况 带宽 CPU 使用率和 GPU 使用率都极其密集的应用程序需要每秒从一个 GPU 向另一个 GPU 传输约 10 15GB 的数据 它使用 DX11 API 来访问 GPU 因此上传到 GPU 只能在每次上传都需要映射的缓冲区中进
  • R foreach问题(某些进程返回NULL)

    我遇到了问题foreach我正在 R 中使用的程序的一部分 该程序用于运行不同参数的模拟 然后将结果返回到单个列表 然后用于生成报告 当并非所有分配的模拟运行都在报告上实际可见时 就会出现问题 从各方面来看 似乎只有分配的运行的一个子集实际
  • Git 中的合并冲突是由什么构成的?

    git 如何确定特定合并存在冲突以及冲突是什么 我的猜测是这样的 如果正在合并的两个提交有一个共同的父提交 并且如果它们都更改了父提交的 X 行 那就是冲突 让我的理解变得复杂的是 更改 X 行 可能意味着用几行新行替换它 但这仍然显示为一
  • 为什么使用小于 32 位的整数?

    我总是喜欢使用最小尺寸的变量 这样效果就很好 但是如果我使用短字节整数而不是整数 并且内存是 32 位字可寻址 这真的会给我带来好处吗 编译器是否会做一些事情来增强内存使用 对于局部变量 它可能没有多大意义 但是在具有数千甚至数百万项的结构

随机推荐

  • Discord.py 狙击命令

    我试图发出一个命令 让机器人 狙击 最后删除的消息 这是我当前的代码 snipe message content None snipe message author None client event async def on messag
  • 如何在 Django 管理中使用 HTML5 颜色选择器

    我正在尝试在 Django 的管理页面中实现 HTML5 颜色选择器 这是我的模型 model py class Category models Model color models CharField max length 7 表格如下
  • 使用 sys/mount.h 挂载 ISO

    我正在尝试在 Linux 中的 C 程序中挂载 ISO 文件 我知道 linux 命令可以实现此目的 即 mount o Loop Test iso mnt myISO 但是 mount 2 手册页声明了以下安装原型 int mount c
  • 字符串到 java.sql.Date

    我意识到这个问题已经被问了很多 我确实看过 我花了几个小时环顾四周并试图找出答案 我应该制作一个程序 在数据库中存储相当于约会列表的内容 其中包含描述 日期 开始时间和结束时间 它必须接受用户的输入来添加或取消约会 据我所知 这意味着我需要
  • 如何在查询中比较模型的两个字段?

    我正在编写一个管理命令 它将用建议价格过滤产品的原始价格 我有一个产品模型 如下所示 class Suggestion models Model price models IntegerField class Product models
  • Python 子进程 wait() 在 Mavericks 和 Yosemite 上的行为不同

    我最近升级到优胜美地 一些用于在 Mavericks 上运行的 Python 脚本被挂起 我的版本是2 7 8 我创建了一个测试用例 import subprocess cat subprocess Popen top l 1 stdout
  • 'And' 与 'AndAlso' 与 vb.net 中的 linq 有关系吗?

    在 vb net 的 linq 查询中使用 And 或 AndAlso 有什么关系吗 我知道在正常操作中 AndAlso 是短路的 因此通常会更快 但我不知道这是否会延续到 linq 查询中 linq 查询是针对数据库还是针对内存集合 这很
  • 固定大小的并发Map

    我需要一张满足以下要求的地图 应该是高并发的 这put get and remove 方法可以由多个线程同时调用 它应该是固定大小的 如果尺寸HashMap达到最大值 例如 10000 则不允许向映射添加新条目 它不能是 LRU 缓存 其中
  • JSON 格式的 Jquery.ajax API 请求在 Chrome 中导致“Uncaught SyntaxError: Unexpected token :”

    我正在尝试查询http developer pintlabs com brewerydb api documentation http developer pintlabs com brewerydb api documentation使用
  • 如何正确刷新curses窗口?

    while 1 window addstr 0 0 abcd window refresh window尺寸为全终端尺寸 大到足以容纳abcd If abcd 被修改为更短的字符串 例如 xyz 然后在终端上我会看到 xyzd 我到底做错了
  • PHP 的 finfo::buffer 如何被欺骗?

    处理上传的文件时 FILES foo type 一点也不可靠 我发现如果您更改 OS X 上的扩展名 类型 会自动更改 相反 请考虑 fileInfo new finfo FILEINFO MIME mimeType fileInfo gt
  • NuGet (NuPack) 智能感知(Visual Studio 包管理器控制台)

    我的 NuGet 智能感知未显示 或者也许有某种捷径 我不认为智能感知是您所期望的 就像在带有可用选项列表的下拉列表中一样 From this page http nuget codeplex com wikipage title Gett
  • 适用于 .NET 的无锁和线程安全 IList

    是否有实现 IList 的无锁且线程安全的数据结构 当然 无锁是指不使用 NET 中的锁定原语而是使用互锁操作 原子操作来实现线程安全的实现 显然在并发数据结构下没有一个 有人见过漂浮在空中的吗 我见过一个java实现氨基 CBBs htt
  • 如何在极坐标中绘制颤动图

    如何在极坐标中绘制颤动图 我有 r 和 theta 方面的数据 我试过了 import numpy as np radii np linspace 0 5 1 10 thetas np linspace 0 2 np pi 20 theta
  • 如何在 TypeScript 中正确导出和导入模块

    Note 我知道有很多关于这个主题的帖子 而且我已经审阅了很多帖子但没有成功 请参阅本文底部的参考资料 我正在尝试使用 Visual Studio Code 在 TypeScript 中运行一个非常简单的测试 其中我在一个文件中声明一个类并
  • 谷歌地方 api 自动完成 - 添加点击事件

    我正在附加一个搜索结果到 google place javascript api 自动完成 到目前为止我正在这样做 var autocomplete function initialize var myLatlng new google m
  • 如何检测“保存/打开/取消”对话框中单击了哪个按钮?

    我有一个网页 会员可以在其中下载不同类型的文件 我不想获取有关每个成员下载了哪些文件以及下载次数的信息 当用户想要下载文件时 他会弹出浏览器 其中有 3 个选择 打开 保存 和 取消 浏览器中的文件对话框 我只想在单击打开 保存按钮时更新下
  • C 中的变量存储在内存的什么位置?

    考虑到内存分为四段 数据段 堆段 堆栈段和代码段 其中分别有全局变量 静态变量 常量数据类型 局部变量 在函数中定义和声明 变量 在主函数中 指针 并且动态分配的空间 使用 malloc 和 calloc 存储在内存中 我认为他们的分配方式
  • QDialog 未从主窗口打开(pyQt)

    我试图通过单击主窗口中的按钮来启动一个对话框 这是我修改的 qtdesigner 生成的 代码只是为了测试它 我已经设置了 showDial 函数以在单击按钮时显示拨号盘 但它不起作用 from PyQt4 import QtCore Qt
  • erlang 是否以任何巧妙的方式实现记录复制和修改?

    given record foo a b c 我做了这样的事情 Thing foo a 1 2 b 3 4 c 5 6 Thing1 Thing foo a 7 8 从语义角度来看 Thing 和 Thing1 是唯一的实体 然而 从语言实