(这篇文章关于高频类型编程)
我最近在一个论坛上看到(我认为他们正在讨论Java),如果你必须解析很多字符串数据,那么使用字节数组比使用split()的字符串更好。确切的帖子是:
使用任何语言,C ++,Java,C#的一个表演技巧是 避免对象创建。它不是分配或GC的成本 访问不适合CPU缓存的大型内存阵列的成本。
现代CPU比内存快得多。他们为很多人而停滞 每个缓存未命中的周期很多。大多数CPU转置预算是 分配用于通过大缓存和大量滴答来减少这种情况。
GPU通过准备好大量线程来解决问题 执行以隐藏内存访问延迟并且很少或没有缓存 将晶体管花在更多核心上。
因此,例如,而不是使用String和split来解析a 消息,使用可以就地更新的字节数组。你真的想要 避免在大型数据结构上进行随机内存访问,至少在 内环。
他只是说“不要使用字符串,因为它们是一个对象并且创建对象是昂贵的”?或者他在说别的什么?
使用字节数组是否确保数据尽可能长时间保留在缓存中? 当你使用字符串时它是否太大而无法保存在CPU缓存中? 一般来说,使用原始数据类型是编写更快代码的最佳方法吗?
答案 0 :(得分:11)
他说如果将块文本分成单独的字符串对象,那么这些字符串对象的 locality 比大文本数组差。每个字符串及其包含的字符数组将在内存中的其他位置;它们可以遍布各处。在处理数据时,内存缓存很可能需要进出才能访问各种字符串。相比之下,一个大型阵列具有最佳可能的位置,因为所有数据都在一个内存区域,并且缓存抖动将保持最小。
当然,这有一些限制:如果文本非常非常大,而你只需要解析其中的一部分,那么这些少数小字符串可能比大块文本更适合缓存。
答案 1 :(得分:2)
使用byte[]
或char*
代替字符串进行HFT还有很多其他原因。字符串由Java中的16位char
组成,并且是不可变的。 byte[]
或ByteBuffer
很容易回收,具有良好的缓存位置,可以脱离堆(直接)保存副本,避免使用字符编码器。这都假定您使用的是ASCII数据。
char*
或ByteBuffers也可以映射到网络适配器以保存另一个副本。 (对于ByteBuffers的一些摆弄)
在HFT中,您很少会同时处理大量数据。理想情况下,您希望在插入Socket时立即处理数据。即一次一个数据包。 (约1.5 KB)