Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/260.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Parallel.ForEach和Regex没有性能提升?_C#_Regex_Multithreading_.net 4.0_Parallel Processing - Fatal编程技术网

C# Parallel.ForEach和Regex没有性能提升?

C# Parallel.ForEach和Regex没有性能提升?,c#,regex,multithreading,.net-4.0,parallel-processing,C#,Regex,Multithreading,.net 4.0,Parallel Processing,我有一个程序,它根据返回的结果以某种方式对返回的结果进行颜色编码。由于对结果进行颜色编码所需的时间很长(目前正在使用Regex和RichTextBox.Select+.SelectionColor进行),我在400个结果时取消了颜色编码。在这个数字上大约需要20秒,这大约是我认为合理的最大时间。 为了提高性能,我重新编写了Regex部分,使用Parallel.ForEach循环迭代匹配集合,但时间大致相同(18-19秒vs 20秒)!难道这不是一项适合并行编程的工作吗?我应该试试别的吗?欢迎任何

我有一个程序,它根据返回的结果以某种方式对返回的结果进行颜色编码。由于对结果进行颜色编码所需的时间很长(目前正在使用Regex和RichTextBox.Select+.SelectionColor进行),我在400个结果时取消了颜色编码。在这个数字上大约需要20秒,这大约是我认为合理的最大时间。

为了提高性能,我重新编写了Regex部分,使用
Parallel.ForEach
循环迭代
匹配集合
,但时间大致相同(18-19秒vs 20秒)!难道这不是一项适合并行编程的工作吗?我应该试试别的吗?欢迎任何建议。谢谢

PS:我觉得有点奇怪,不管有没有Parallel.ForEach,我的CPU利用率从未达到14%

代码

MatchCollection startMatches = Regex.Matches(tempRTB.Text, startPattern);

object locker = new object();
System.Threading.Tasks.Parallel.ForEach(startMatches.Cast<Match>(), m =>
{
    int i = 0;
    foreach (Group g in m.Groups)
    {
        if (i > 0 && i < 5 && g.Length > 0)
        {
            tempRTB.Invoke(new Func<bool>(
                delegate
                {
                    lock (locker)
                    {
                        tempRTB.Select(g.Index, g.Length);
                        if ((i & 1) == 0) // Even number
                            tempRTB.SelectionColor = Namespace.Properties.Settings.Default.ValueColor;
                        else              // Odd number
                            tempRTB.SelectionColor = Namespace.Properties.Settings.Default.AttributeColor;
                        return true;
                    }
                }));
        }
        else if (i == 5 && g.Length > 0)
        {
            var result = tempRTB.Invoke(new Func<string>(
                delegate
                {
                    lock (locker)
                    {
                        return tempRTB.Text.Substring(g.Index, g.Length);
                    }
                }));

            MatchCollection subMatches = Regex.Matches((string)result, pattern);

            foreach (Match subMatch in subMatches)
            {
                int j = 0;
                foreach (Group subGroup in subMatch.Groups)
                {
                    if (j > 0 && subGroup.Length > 0)
                    {
                        tempRTB.Invoke(new Func<bool>(
                            delegate
                            {
                                lock (locker)
                                {
                                    tempRTB.Select(g.Index + subGroup.Index, subGroup.Length);
                                    if ((j & 1) == 0) // Even number
                                        tempRTB.SelectionColor = Namespace.Properties.Settings.Default.ValueColor;
                                    else              // Odd number
                                        tempRTB.SelectionColor = Namespace.Properties.Settings.Default.AttributeColor;
                                    return true;
                                }
                            }));
                    }
                    j++;
                }
            }
        }
        i++;
    }
});
MatchCollection startMatches=Regex.Matches(tempRTB.Text,startPattern);
对象锁定器=新对象();
System.Threading.Tasks.Parallel.ForEach(startMatches.Cast(),m=>
{
int i=0;
foreach(m组中的g组)
{
如果(i>0&&i<5&&g.长度>0)
{
tempRTB.Invoke(新函数(
代表
{
锁(储物柜)
{
tempRTB.Select(g.Index,g.Length);
if((i&1)==0)//偶数
tempRTB.SelectionColor=Namespace.Properties.Settings.Default.ValueColor;
else//奇数
tempRTB.SelectionColor=Namespace.Properties.Settings.Default.AttributeColor;
返回true;
}
}));
}
如果(i==5&&g.长度>0)为else
{
var result=tempRTB.Invoke(新函数(
代表
{
锁(储物柜)
{
返回tempRTB.Text.Substring(g.Index,g.Length);
}
}));
MatchCollection subMatches=Regex.Matches((字符串)结果,模式);
foreach(在子匹配中匹配子匹配)
{
int j=0;
foreach(子匹配组中的组子组)
{
如果(j>0&&subGroup.Length>0)
{
tempRTB.Invoke(新函数(
代表
{
锁(储物柜)
{
tempRTB.Select(g.Index+subGroup.Index,subGroup.Length);
if((j&1)==0)//偶数
tempRTB.SelectionColor=Namespace.Properties.Settings.Default.ValueColor;
else//奇数
tempRTB.SelectionColor=Namespace.Properties.Settings.Default.AttributeColor;
返回true;
}
}));
}
j++;
}
}
}
i++;
}
});

代码中的大部分时间很可能花在实际选择richtext框中的文本并设置颜色的部分

这段代码不可能并行执行,因为它必须被封送到UI线程,这是通过
tempRTB.Invoke
完成的

此外,通过使用
lock
语句明确确保高亮显示不是并行执行,而是顺序执行。这是不必要的,因为所有这些代码都是在单个UI线程上运行的


您可以尝试通过在RTB中选择文本并为其上色时暂停UI布局来提高性能:

tempRTB.SuspendLayout();

// your loop

tempRTB.ResumeLayout();

实际上,程序的任何方面都不能并行运行

需要按顺序生成匹配项。在找到第一个匹配项之前,它无法找到第二个匹配项
Parallel.ForEach
最多允许您并行处理序列的结果,但它们仍然是按顺序生成的。这就是你大部分耗时的工作似乎都在做的地方,而且没有任何收获

除此之外,您也没有真正并行处理结果。循环体中运行的大部分代码都在对UI线程的调用中,这意味着它都由单个线程运行


简言之,只有一小部分程序实际上是并行运行的,通常使用并行化会增加一些开销;听起来你的开销几乎没有超过这个。实际上你没有做错什么,操作本身就不适合并行化,除非有一种有效的方法将初始字符串分解成几个较小的卡盘,正则表达式可以单独(并行)解析.

14%的利用率听起来像是四核上的一个核的利用率达到了100%。您的机器上有多少个核?@LukeHennerley Task manager显示8(它是Intel i7-3770)为什么在
Invoke
语句中有锁块?根据定义,由于您使用的是
Invoke
,因此代码只能在一个线程上运行,因此不会出现同步问题。@Hershizer33:这证实了我的怀疑:100%的总体CPU利用率/8个内核=12,5%,如果一个内核的利用率为100%。-->您的UI线程正在完全利用其核心。我明白了,我认为这是有道理的。那么它是什么呢?保持400个结果的硬限制,20秒生存?@Hershizer33:你可以尝试减少disa选择的时间