【发布时间】:2014-11-11 22:10:25
【问题描述】:
我正在尝试创建一个程序来解析游戏聊天日志中的数据。到目前为止,我已经设法让程序运行并解析我想要的数据,但我的问题是程序变得越来越慢。
目前解析一个 10MB 的文本文件需要 5 秒,我注意到如果我将 RegexOptions.Compiled 添加到我的正则表达式,它会下降到 3 秒。
我相信我已经确定了我的正则表达式匹配的问题。由于 5 个正则表达式,当前一行被读取了 5 次,所以当我稍后添加更多时,程序会变得更慢。
我应该怎么做才能使我的程序不会因多个正则表达式而变慢?感谢所有使代码更好的建议!
if (sender.Equals(ButtonParse))
{
var totalShots = 0f;
var totalHits = 0f;
var misses = 0;
var crits = 0;
var regDmg = new Regex(@"(?<=\bSystem\b.* You inflicted )\d+.\d", RegexOptions.Compiled);
var regMiss = new Regex(@"(?<=\bSystem\b.* Target evaded attack)", RegexOptions.Compiled);
var regCrit = new Regex(@"(?<=\bSystem\b.* Critical hit - additional damage)", RegexOptions.Compiled);
var regHeal = new Regex(@"(?<=\bSystem\b.* You healed yourself )\d+.\d", RegexOptions.Compiled);
var regDmgrec = new Regex(@"(?<=\bSystem\b.* You take )\d+.\d", RegexOptions.Compiled);
var dmgList = new List<float>(); //New list for damage values
var healList = new List<float>(); //New list for heal values
var dmgRecList = new List<float>(); //New list for damage received values
using (var sr = new StreamReader(TextBox1.Text))
{
while (!sr.EndOfStream)
{
var line = sr.ReadLine();
var match = regDmg.Match(line);
var match2 = regMiss.Match(line);
var match3 = regCrit.Match(line);
var match4 = regHeal.Match(line);
var match5 = regDmgrec.Match(line);
if (match.Success)
{
dmgList.Add(float.Parse(match.Value, CultureInfo.InvariantCulture));
totalShots++;
totalHits++;
}
if (match2.Success)
{
misses++;
totalShots++;
}
if (match3.Success)
{
crits++;
}
if (match4.Success)
{
healList.Add(float.Parse(match4.Value, CultureInfo.InvariantCulture));
}
if (match5.Success)
{
dmgRecList.Add(float.Parse(match5.Value, CultureInfo.InvariantCulture));
}
}
TextBlockTotalShots.Text = totalShots.ToString(); //Show total shots
TextBlockTotalDmg.Text = dmgList.Sum().ToString("0.##"); //Show total damage inflicted
TextBlockTotalHits.Text = totalHits.ToString(); //Show total hits
var hitChance = totalHits / totalShots; //Calculate hit chance
TextBlockHitChance.Text = hitChance.ToString("P"); //Show hit chance
TextBlockTotalMiss.Text = misses.ToString(); //Show total misses
var missChance = misses / totalShots; //Calculate miss chance
TextBlockMissChance.Text = missChance.ToString("P"); //Show miss chance
TextBlockTotalCrits.Text = crits.ToString(); //Show total crits
var critChance = crits / totalShots; //Calculate crit chance
TextBlockCritChance.Text = critChance.ToString("P"); //Show crit chance
TextBlockDmgHealed.Text = healList.Sum().ToString("F1"); //Show damage healed
TextBlockDmgReceived.Text = dmgRecList.Sum().ToString("F1"); //Show damage received
var pedSpent = dmgList.Sum() / (float.Parse(TextBoxEco.Text, CultureInfo.InvariantCulture) * 100); //Calculate ped spent
TextBlockPedSpent.Text = pedSpent.ToString("0.##") + " PED"; //Estimated ped spent
}
}
这是一个示例文本:
2014-09-02 23:07:22 [System] [] You inflicted 45.2 points of damage.
2014-09-02 23:07:23 [System] [] You inflicted 45.4 points of damage.
2014-09-02 23:07:24 [System] [] Target evaded attack.
2014-09-02 23:07:25 [System] [] You inflicted 48.4 points of damage.
2014-09-02 23:07:26 [System] [] You inflicted 48.6 points of damage.
2014-10-15 12:39:55 [System] [] Target evaded attack.
2014-10-15 12:39:58 [System] [] You inflicted 56.0 points of damage.
2014-10-15 12:39:59 [System] [] You inflicted 74.6 points of damage.
2014-10-15 12:40:02 [System] [] You inflicted 78.6 points of damage.
2014-10-15 12:40:04 [System] [] Target evaded attack.
2014-10-15 12:40:06 [System] [] You inflicted 66.9 points of damage.
2014-10-15 12:40:08 [System] [] You inflicted 76.2 points of damage.
2014-10-15 12:40:12 [System] [] You take 18.4 points of damage.
2014-10-15 12:40:14 [System] [] You inflicted 76.1 points of damage.
2014-10-15 12:40:17 [System] [] You inflicted 88.5 points of damage.
2014-10-15 12:40:19 [System] [] You inflicted 69.0 points of damage.
2014-10-19 05:56:30 [System] [] Critical hit - additional damage! You inflict 275.4 points of damage.
2014-10-19 05:59:29 [System] [] You inflicted 92.8 points of damage.
2014-10-19 05:59:31 [System] [] Critical hit - additional damage! You inflict 251.5 points of damage.
2014-10-19 05:59:35 [System] [] You take 59.4 points of damage.
2014-10-19 05:59:39 [System] [] You healed yourself 84.0 points.
【问题讨论】:
-
不要使用lookarounds(可变长度lookbehinds,即
(?<=...)),而是使用捕获组(...)来获取您感兴趣的值。 -
非常感谢 Qtax!我不知道lookbehind对性能的影响,现在我了解了分组。现在处理整个事情只需不到一秒钟的时间。