问题标签 [storable]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
optimization - 为 union struct 编写可存储向量定义时的优化建议
我为下面的数据类型写了一个可存储的向量实例(这里的原始问题):
为可存储向量定义这些实例的代码如下。虽然我使用下面的代码获得了非常好的性能,但我对提高该可存储实例的性能的通用建议非常感兴趣。通过一般性建议,我的意思是:
- 它不特定于 GHC 编译器版本。您可以假设 GHC 6.12.3+ 排除了早期版本中存在的性能错误,并且与此处的代码相关。
- 特定于平台的建议是可以的。您可以假设 x86_64 Linux 平台。
- 比利用硬件特定优化的建议更有价值的是算法改进(大 O)形式的通用建议。但是,鉴于这里的 peek/poke 等基本操作,据我所知,算法改进的余地不大(因此更有价值,因为它是一种稀缺商品:)
- x86_64 的编译器标志是可接受的(例如,告诉编译器删除浮点安全检查等)。我正在使用“-O2 --make”选项来编译代码。
如果有任何已知的优秀库源代码可以做类似的事情(即,为联合/递归数据类型定义可存储实例),我将对检查它们非常感兴趣。
更新:
根据 Daniel 和 dflemstr 的反馈,我重写了对齐方式,并将构造函数更新为 Word32 类型而不是 Word8。但是,似乎要使其有效,数据构造函数也应该更新为具有未打包的值——这是我的疏忽。我应该首先编写数据构造函数来获得解压缩的值(参见John Tibbell 的性能幻灯片- 幻灯片 #49)。因此,重写数据构造函数,再加上对齐和构造函数的更改,对性能产生了很大影响,将函数比向量提高了大约 33%(我的基准测试中的一个简单的 sum 函数)。以下相关更改(警告 - 不可移植,但对我的用例来说不是问题):
数据构造函数更改:
可存储的 sizeof 和对齐更改:
haskell - 使用 O(1) 函数为 CString 编写可存储实例以获得总字节长度
我正在尝试为 CString (在我的例子中为空终止的 C 字符)编写一个可存储的向量实例。可存储实例将存储 CString 为 (Ptr CChar) 的指针。因此,向量的长度是 CString 指针的数量。现在,我编写这个可存储实例的原因是因为它将用于从 FFI CString 进行零复制,然后使用 unsafeCreate 快速构建 ByteString(经过一些转换 - 因此,我们在这里使用快速向量进行中间操作)。为了进行快速的 ByteString 构建,可存储实例需要三件事:
- 总长度(以字节为单位) - 可存储实例在将每个 CString 添加到向量时需要进行簿记分配,用于存储每个 CString 的长度,以及到目前为止存储的 CString 的总长度。假设 C 字符串的总长度不能超过 2^31。因此,Int32/Word32 将存储每个 CString 的长度和总长度。
- 存储 CString 及其长度的函数 - O(n) 时间。此函数将遍历 CString,并存储其长度,并将总长度增加 CString 的长度。
- 返回总字节长度的函数 - O(1) 时间。此函数将仅从存储总长度的字段中检索值
虽然我知道如何编写自定义可存储实例,但我不知道如何处理这种情况。一个简单的代码(可以是一个简单的玩具示例),展示如何进行自定义簿记,并编写函数来存储/获取簿记结果将非常感激。
更新 1(澄清)
在我的例子中使用可存储向量实例的原因有两个:使用未装箱类型的快速计算/转换(通过 C FFI 接收的实时数据),以及快速转换为字节串(实时发送数据) IPC 到另一个程序)。对于快速的字节串转换,unsafeCreate 非常好。但是,我们必须知道要分配多少,并且还要传递一个函数进行转换。给定一个可存储的向量实例(具有混合类型 - 我将上面的问题简化为 CString 类型),我很容易构建一个快速转换函数,该函数遍历向量的每个元素并将其转换为字节串。然后,我们简单地将它传递给 unsafeCreate。但是,我们还必须传递要分配的字节数。AO(n) 递归字节长度计算函数太慢,并且可以使构建字节串的开销增加一倍。
haskell - 为涉及向量的递归数据结构定义可存储
我有以下形式的数据结构(V 是 Data.Storable.Vector):
我首先为非递归形式(即没有T
构造函数)编写了一个自定义的可存储定义。然后,我尝试添加自定义 peek 和 poke 定义以供T
使用ForeignPtr
和length
来自Vector
(代码如下)的信息。GHC 编译器抱怨Storable
没有为ForeignPtr Elems
类型定义实例。我的问题是是否可以在 Storable 定义中将 ptr 存储到 Vector,而不必为 ForeignPtr 编写 Storable 实例定义。
从Haddocs文档中,ForeignPtr 似乎只是一个分配有终结器的 Ptr:
ForeignPtrs 和 Ptr a 类型的普通内存引用之间的本质区别在于前者可能与终结器相关联。
由于最终确定它的问题,我不想通过使用Ptr
而不是解决这个问题。ForeignPtr
所以,我更喜欢存储 ForeignPtr 的位置(通过Ptr (ForeignPtr a)
),以便 GHC 垃圾收集器知道对它的引用。但是,这种方法会迫使我定义一个Storable instance
(因为约束(Storable a) => Ptr a
是有意义的)。
有没有办法在 Storable 中将 ptr 存储和检索到 Vector 中,而无需为 ForeignPtr 定义 Storable 实例?如果没有,那么编写 ForeignPtr 的 Storable 定义是必须的。在那种情况下,它会是什么样子?我的猜测是它只会将 Ptr 存储到 ForeignPtr。
完整代码如下:
haskell - 将混合可存储向量传递给 C 函数
我有一个向量列表 - 类型集是已知且固定的 - 让我们说,CInt
并且CChar
. 该列表在编译时是未知的 - 组成将在运行时从配置文件中确定。例如,我们可能决定需要将两个向量传递给C
函数:一个CInt
长度为 10 的CChar
向量,一个长度为 50 的向量。至于 C 函数如何解释它们,我可以通过传递一个向量编码每个向量的类型来处理该逻辑 (比如说,0 => CInt
, 1 => CChar
),以及传递的每个向量的向量编码长度 (10,50)。
我想弄清楚的是如何生成混合向量的向量(仅用于传递给C)。我尝试了一个像下面这样的玩具解决方案(它模拟了相同的想法 - 生成Ptr
混合类型的可存储向量 - 在实际代码中,每个 Ptr 将指向另一个可存储向量)。由于类型错误而失败 - 我怀疑它与 ehird 之前在我之前提出的另一个问题中指出的存在限定类型有关。由于我使用 Storable 实例传递给 C FFI,我想我无法包装类型(不定义另一个可存储实例)。
ghci 7.4.1 中的错误:
我将不胜感激有关如何解决上述问题的指示。我可以使用 Data.Vector.Storable.Mutable.new 和 unsafeWrite 编写自定义向量填充函数,但我仍然需要适应混合类型。
perl - 通过 UDP 发送数据包
我试图通过套接字发送一个标量值,这是我从可存储的 nfreeze 获得的。一步步:
- 我得到标量
$serializedHash = nfreeze \%hash;
- 我想通过套接字发送它
$sendSocket->send($serializedHash);
只要标量$serializedHash
不大于 1024 字节,就可以正常工作。因为我在另一边有一个只能接收最大数据的套接字。长度为 1024 字节。我也不能存储$serializedHash
在一个文件中,然后用sysread
and处理它syswrite
。
我不想要的是发送每个套接字的每一行,因为我的哈希有超过 200 万个条目。哈希元素由 a 分隔,\n
所以我尝试使用该split
函数,但后来我有一个包含 200 万个条目的数组。
如何通过 UDP 套接字以包的形式发送数据?
perl - How to use Perl Storable, changing a hash value
I'm no Perl expert, so this is probably an easy question.
I've been using Storable, and following this example to store a hash. First, I store the original hash.
Then I retrieve it. (different script)
My question is how can I change one of the hash values? For example, do something like
in the second script.
perl - Perl 可存储的权限被拒绝
我正在尝试在 perl CGI 应用程序中保留数据(单击提交按钮时)。但是下面的代码:
返回:
如何授予脚本保存数据的权限?
perl - 无法解冻使用 Storable::nfreeze 存储的数据结构?
我有一堆数据存储在 MySQL 表的单个列中。我可以访问大约 5 年的 perl 代码,该代码将其存储在那里,并且可以看到它是Storable::nfreeze
在存储之前被冻结的所有哈希值。MySQL 列是TEXT
并且表设置为latin1
编码。我现在正在尝试检索这些数据以进行一次性导出。我知道该应用程序最初是在 perl 5.8.x 上运行的,所以我正在尝试使用 perl-5.8.8。不幸的是,我不知道使用的是什么版本的 Storable。
我首先尝试使用最新的 Storable 2.39。这给了我:
使用 Storable-2.14 我得到
使用 Storable-2.13 我得到
>= 2.14 中不合理的高二进制图像数字让我认为解析数字的方式发生了一些变化。我相信这段代码可能在 32 位操作系统上运行,现在我正在 64 位机器上尝试这个,这可能是相关的吗?接下来是我将尝试运行 2.13 和 2.14 之间的差异,看看我是否能找出导致变化的原因。
任何人都可以提供任何指导吗?
谢谢!
perl - 在 perl 中对序列化数据结构使用解冻时出现问题
我正在使用 perl DB_File 模块将哈希变量保存到文件中。
我的散列变量包含作为普通字符串的键和作为另一个散列变量的值。
我曾经Storable::freeze(\%value);
序列化哈希值。
但是当我试图检索这些值时,我得到了一个错误。当我第一次运行检索代码时,它可以工作。接下来的连续几次,它失败了。
我使用了这样的方法:
错误信息
可存储二进制映像 v25.47 比我 (v2.7) 更新,位于 ../../lib/Storable.pm(自动拆分为 ../../lib/auto/Storable/thaw.al)第 366 行,在 ../../lib/Storable.pm 的retrieve.pl 第 15 行(自动拆分为 ../../lib/auto/Storable/logcroak.al) 第 74 行 Storable::logcroak('') 调用于 . ./../lib/Storable.pm (autosplit into ../../lib/auto/Storable/thaw.al) 第 367 行 Storable::thaw('2/8') 在 retrieve.pl 第 15 行调用