如何将 ByteString 转换为适当大小的 Word?

发布于 2024-12-05 10:48:04 字数 354 浏览 5 评论 0原文

基本上我已经读取了对应于数量的 5 个字节,但我想将其转换为 Word64。最好的方法是什么?

编辑:我还应该说,这是在内部循环中运行的,因此性能至关重要。理想情况下 我想做一些类似的事情:

uint64_t word = 0;
char bytes[5] = getbytes(5)
word += (bytes[0] << 32) 
        + (bytes[1] << 24) 
        + (bytes[2] << 16) 
        + (bytes[3] << 8) 
        + (bytes[4])

或者类似的事情。

Basically I've read in 5 bytes that correspond to a quantity, but I would like to convert it to a Word64. What's the best way to do this?

Edit: I should also say that this is run in an inner loop so performance is critical. Ideally
I'd like to do something like:

uint64_t word = 0;
char bytes[5] = getbytes(5)
word += (bytes[0] << 32) 
        + (bytes[1] << 24) 
        + (bytes[2] << 16) 
        + (bytes[3] << 8) 
        + (bytes[4])

Or something similar.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

无畏 2024-12-12 10:48:04

如果您只想要一个简单的函数,假设采用大端字节顺序,那么这个函数应该可以完成这项工作:

foo :: B.ByteString -> Word64
foo = B.foldl' (\x y -> x * 256 + fromIntegral y) 0

但是,如果您正在读取大量二进制数据,您可能需要考虑使用 二进制

If you just want a simple function, assuming big-endian byte order, this one should do the job:

foo :: B.ByteString -> Word64
foo = B.foldl' (\x y -> x * 256 + fromIntegral y) 0

However, if you are reading lots of binary data, you might want to look into using the binary package.

淡淡の花香 2024-12-12 10:48:04

正如哈马尔所说,二进制(以及严格的字节串版本,谷物)很棒,但它们比最快的解决方案慢得多(它们执行哈马尔解决方案中提出的相同移位)。

我发现简单的 FFI 例程是最快的解决方案:

getNthWord n b = inlinePerformIO (unsafeUseAsCString b (flip peekElemOff n . castPtr))

如果您愿意添加构建依赖,同样快速的解决方案是使用矢量包中的 Vector.Storable

请注意,这些都不能处理您的 5 字节大端格式,因此您需要更改数据生成器才能使其有用。

PS FFI 解决方案假设字对齐。当用户在非 x86 系统上运行该例程时,我最初遇到了一个错误。

As Hammar said, binary (and the strict bytestring version, cereal) is great, but they are measuably slower than the fastest solutions (they perform the same shifting proposed in Hammar's solution).

I've found that a simple FFI routine is the fastest solution:

getNthWord n b = inlinePerformIO (unsafeUseAsCString b (flip peekElemOff n . castPtr))

If you're willing to add a build-dep, an equally fast solution is to use Vector.Storable from the vector package.

Note neither of these handle your 5 byte big endian format, so you'd need to alter the data producer for this to be useful.

PS The FFI solution assumes word alignment. I originally had a bug when users ran that routine on non-x86 systems.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文