2

使用多个正则表达式命令(总共大约 20 个)解析消息时,我遇到了性能问题:

为了提高效率,我有:

1) 按可能性对正则表达式命令进行排序。

2)确保一旦找到匹配项,我就会跳出匹配循环。

我想知道我是否可以进行任何其他改进,或者是否有更好的方法来解决我的问题。

调用代码:

        bool resolved = false;
        Match regexMatch = null;

        foreach (var resolverKvp in _resolvers)
        {
            if (resolverKvp.Key.Pattern.IsMatch(topicName))
            {
                regexMatch = resolverKvp.Key.Pattern.Match(topicName);
                //  Use the kvp value
                resolved = true;
                break;
            }
        }

迭代的正则表达式命令示例:

    <add messagename="BackLayVolumeCurrencyOddsFormat" pattern="^.*/M/E_([0-9]+)/MEI/MDP/(\d{1,3})_(\d{1,3})_(\d+)_([a-zA-Z]{3})_([1-3])$" assembly="Client.Messaging"
      type="Client.Messaging.TopicMessages.BackLayVolumeCurrencyOddsFormatResolver">
    </add>

    <add messagename="Market1" pattern="^.*/M/E_([0-9]+)$" assembly="Client.Messaging"
      type="Client.Messaging.TopicMessages.Market1Resolver">
    </add>

数据示例:

regex 1:
6/E/E_1/E/E_511010/E/E_527901/E/E_631809/E/E_631810/E/E_631811/M/E_1379656/MEI/MDP/10_10_1_USD_3

regex 2:
1/E/E_1/E/E_100004/E/E_190539/E/E_632113/E/E_632120/M/E_1380084

先感谢您。

4

2 回答 2

3

首先(小)值得注意的是,找到的正则表达式被执行了两次:一次检查匹配,然后查找匹配。不确定 ismatch 给出了多少性能差异,但您可以结合检查并找到:

regexMatch = resolverKvp.Key.Pattern.Match(topicName);
if (regexMatch.Success)
{
      //etc
于 2012-06-12T10:14:07.230 回答
1

要尝试的一件事是避免.*在你的表达中。在您的示例中,它似乎不需要,而且它不是免费的,尤其是在表达式不匹配的情况下。一个非常快速而肮脏的测试显示,您的模式 1 和没有该^.*部件的等价物之间有两倍的系数。

此外,.*在表达式中多次使用可能会导致灾难性的回溯

于 2012-06-12T10:20:37.287 回答