字符串与字节数组,性能

时间:2011-10-24 13:46:38

标签: c# java c++ oop

(这篇文章关于高频类型编程)

我最近在一个论坛上看到(我认为他们正在讨论Java),如果你必须解析很多字符串数据,那么使用字节数组比使用split()的字符串更好。确切的帖子是:

  

使用任何语言,C ++,Java,C#的一个表演技巧是   避免对象创建。它不是分配或GC的成本   访问不适合CPU缓存的大型内存阵列的成本。

     

现代CPU比内存快得多。他们为很多人而停滞   每个缓存未命中的周期很多。大多数CPU转置预算是   分配用于通过大缓存和大量滴答来减少这种情况。

     

GPU通过准备好大量线程来解决问题   执行以隐藏内存访问延迟并且很少或没有缓存   将晶体管花在更多核心上。

     

因此,例如,而不是使用String和split来解析a   消息,使用可以就地更新的字节数组。你真的想要   避免在大型数据结构上进行随机内存访问,至少在   内环。

他只是说“不要使用字符串,因为它们是一个对象并且创建对象是昂贵的”?或者他在说别的什么?

使用字节数组是否确保数据尽可能长时间保留在缓存中? 当你使用字符串时它是否太大而无法保存在CPU缓存中? 一般来说,使用原始数据类型是编写更快代码的最佳方法吗?

2 个答案:

答案 0 :(得分:11)

他说如果将块文本分成单独的字符串对象,那么这些字符串对象的 locality 比大文本数组差。每个字符串及其包含的字符数组将在内存中的其他位置;它们可以遍布各处。在处理数据时,内存缓存很可能需要进出才能访问各种字符串。相比之下,一个大型阵列具有最佳可能的位置,因为所有数据都在一个内存区域,并且缓存抖动将保持最小。

当然,这有一些限制:如果文本非常非常大,而你只需要解析其中的一部分,那么这些少数小字符串可能比大块文本更适合缓存。

答案 1 :(得分:2)

使用byte[]char*代替字符串进行HFT还有很多其他原因。字符串由Java中的16位char组成,并且是不可变的。 byte[]ByteBuffer很容易回收,具有良好的缓存位置,可以脱离堆(直接)保存副本,避免使用字符编码器。这都假定您使用的是ASCII数据。

char*或ByteBuffers也可以映射到网络适配器以保存另一个副本。 (对于ByteBuffers的一些摆弄)

在HFT中,您很少会同时处理大量数据。理想情况下,您希望在插入Socket时立即处理数据。即一次一个数据包。 (约1.5 KB)