我需要尽快解析FIX消息。
我的方法如下。我在FP_FixString中保留了对FixString的引用,然后我按顺序完成了我需要的Tag值。
修复消息很大(我需要提取大约4,000个字符和大约100个重复的3个标记组)。
我是否尽可能高效地做到这一点?从字符串构建和解析角度来看?
public FixParser
{
string FP_FixString;
int FP_m;
int FP_Lastm;
public void Go()
{
using (StreamReader reader = new StreamReader(new GZipStream(File.OpenRead(@"L:\Logs\FIX.4.2-D.messages.current.log.20140512T.gz"), CompressionMode.Decompress)))
{
string line = "";
while ( (line = reader.ReadLine()) != null)
{
InitiateFixParse(ref line);
string Symbol;
if (!GetTagString(55, out Symbol))
return;
//DO ALL OTHER PROCESSING OF TAGS HERE
}
}
public void InitiateFixParse(ref string fixString)
{
FP_Lastm = fixString.Length - 1;
FP_FixString = fixString;
FP_m = 0;
}
public bool IsEndMark()
{
if (FP_m>=FP_Lastm || FP_FixString[FP_m].Equals('\x01'))
return true;
return false;
}
public bool NextTag(out int Tag, out string ValueString)
{
Tag = 0;
ValueString = "";
if(FP_m>=FP_Lastm)
return false;
string TagString = "";
bool GettingTag=true;
while (!IsEndMark())
{
if (FP_FixString[FP_m].Equals('='))
{
GettingTag = false;
FP_m++;
}
if(GettingTag)
TagString = TagString + FP_FixString[FP_m];
else
ValueString = ValueString + FP_FixString[FP_m];
FP_m++;
}
Tag=int.Parse(TagString);
FP_m++; //Start of next Tag
return true;
}
public bool GetTagString(int Tag, out string ValueString)
{
//bool FountIt = false;
int aTag;
string aValueString;
while (NextTag(out aTag, out aValueString))
{
if (aTag == Tag)
{
ValueString = aValueString;
return true;
}
}
ValueString = "";
return false;
}
}
答案 0 :(得分:1)
我乍一看的唯一建议是用StringBuilders替换循环中的字符串连接,例如TagString = TagString + FP_FixString[FP_m];
。
StringBuilder sb = new StringBuilder();
while (!IsEndMark())
{
sb.append(FP_FixString[FP_m]);
}
TagString = sb.ToString();
因为StringBuilder 比循环中的连接更有效。通常的警告适用。我同意@DumbCoder的分析是一个好主意。
另外,最好存储消息的FIXml表示,并尽可能使用xpath提取数据(即如果您不是要尝试解析自动创建的日志),因为它可以帮助解决一些问题。重复小组问题,或者说它在我这里做了!
答案 1 :(得分:0)
如果您正在处理非常大的文件,您希望尽可能地避免GC压力,如前所述。 StringBuilder有帮助,但您仍在创建StringBuilder实例。一些快速的胜利:
if (GettingTag)
{
//TagString = TagString + FP_FixString[FP_m];
Tag = Tag * 10 + ((byte)FP_FixString[FP_m] -48);
}// This reduces time by about 40%
//Tag = int.Parse(TagString);
以下代码进一步缩短了时间(减少到原始时间的50%):
int valueStart = 0;
while (!IsEndMark())
{
if (FP_FixString[FP_m].Equals('='))
{
GettingTag = false;
FP_m++;
valueStart = FP_m;
}
if (GettingTag)
{
//TagString = TagString + FP_FixString[FP_m];
Tag = Tag * 10 + ((byte)FP_FixString[FP_m] -48);
}
//else
//ValueString = ValueString + FP_FixString[FP_m];
FP_m++;
}
ValueString = FP_FixString.Substring(valueStart, FP_m - valueStart);
//Tag = int.Parse(TagString);
FP_m++; //Start of next Tag
我没有进一步查看代码。