我碰到这个非常相似的问题 https://stackoverflow.com/questions/2311205/the-best-way-to-parse-a-fix-message但该问题被标记为 QuickFIX(与我的问题无关),并且大多数答案都与 QuickFIX 相关。
我的问题更广泛。我正在寻找解析 a 的最有效方法固定协议 http://fixprotocol.org/使用 C# 发送消息。作为背景,FIX 消息由一系列由 ASCII 分隔的标记/值对组成<SOH>
字符(0x01)。消息中的字段数量是可变的。
示例消息可能如下所示:
8=FIX.4.2<SOH>9=175<SOH>35=D<SOH>49=BUY1<SOH>56=SELL1<SOH>34=2482<SOH>50=frg<SOH>
52=20100702-11:12:42<SOH>11=BS01000354924000<SOH>21=3<SOH>100=J<SOH>55=ILA SJ<SOH>
48=YY77<SOH>22=5<SOH>167=CS<SOH>207=J<SOH>54=1<SOH>60=20100702-11:12:42<SOH>
38=500<SOH>40=1<SOH>15=ZAR<SOH>59=0<SOH>10=230<SOH>
对于每个字段,标记(整数)和值(出于我们的目的,是字符串)由“=”字符分隔。 (每个标签的精确语义在协议中定义,但这与这个问题并不是特别密切。)
通常情况下,在进行基本解析时,您只对 FIX 标头中的少数特定标记感兴趣,而不是真正对每个可能的字段进行随机访问。我考虑过的策略包括:
Using String.Split
,迭代每个元素并将标签放入哈希表中的索引映射 - 如果在某些时候需要的话,提供对所有字段的完全随机访问
(轻微优化)使用String.Split
,扫描数组中感兴趣的标签,并将标签到索引映射放入另一个容器(不一定是哈希表,因为它可能是相当少量的项目,并且项目数量在解析之前已知)
使用逐个字段扫描消息字段String.IndexOf
并将感兴趣的字段的偏移量和长度存储在适当的结构中
关于前两个 - 尽管我的测量表明String.Split
相当快,根据文档 http://msdn.microsoft.com/en-us/library/b873y76a.aspx该方法为结果数组的每个元素分配一个新的字符串,如果您正在解析大量消息,这可能会生成大量垃圾。谁能找到更好的方法来解决 .NET 中的这个问题?
EDIT:
我遗漏了三个重要信息:
标签在 FIX 消息中不一定是唯一的,即在某些情况下可能会出现重复的标签。
某些类型的 FIX 字段可以包含“嵌入”<SOH>
' 在数据中 - 这些标签被称为“数据”类型 - 字典列出了这种类型的标签号。
最终的要求是能够编辑消息(特别是替换值)。
假设您通过网络获取这些消息或从磁盘加载它们。无论哪种情况,您都可以将它们作为字节数组进行访问,并以正向读取的方式读取字节数组。如果您想要/需要/要求高性能,请自己解析字节数组(为了高性能,不要使用标签和值的哈希表字典,因为相比之下,这非常慢)。自己解析字节数组还意味着您可以避免使用您不感兴趣的数据,并且可以优化解析以反映这一点。
您应该能够轻松避免大多数对象分配。您可以非常轻松且快速地将 FIX float 数据类型解析为双精度数,而无需创建对象(您可以使用自己的版本在此处大大超越 double.parse)。您可能需要更多考虑的唯一问题是字符串形式的标签值,例如FIX 中的符号值。为了避免在这里创建字符串,您可以想出一种简单的方法来确定每个符号(这是一种值类型)的唯一 int 标识符,这将再次帮助您避免在堆上分配。
正确完成的消息的自定义优化解析应该可以轻松超越 QuickFix,并且您可以在 .NET 或 Java 中无需垃圾回收即可完成这一切。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)