为什么OfType<>比演员LT更快;&GT ;? [英] Why is OfType<> faster than Cast<>?

查看:280
本文介绍了为什么OfType<>比演员LT更快;&GT ;?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在回答以下问题:
如何MatchCollection转换为字符串数组

给出的两个LINQ表达式:

Given The two Linq expressions:

var arr = Regex.Matches(strText, @"\b[A-Za-z-']+\b")
    .OfType<Match>() //OfType
    .Select(m => m.Groups[0].Value)
    .ToArray();

var arr = Regex.Matches(strText, @"\b[A-Za-z-']+\b")
    .Cast<Match>() //Cast
    .Select(m => m.Groups[0].Value)
    .ToArray();



&OfType LT;>是由用户的亚历克斯的速度(并确认我自己)要稍好。

OfType<> was benchmarked by user Alex to be slightly faster (and confirmed by myself).

这似乎违反直觉给我,因为我还以为OfType< ;>将不得不这样做既是一个'是'的比较,的的强制转换(T)

This seems counterintuitive to me, as I'd have thought OfType<> would have to do both an 'is' comparison, and a cast (T).

任何启示,将不胜感激,为什么。这样的话:。)

Any enlightenment would be appreciated as to why this is the case :)

推荐答案

我的基准不符合您的基准同意

My benchmarking does not agree with your benchmarking.

我跑了相同的基准Alex的,并得到了相反的结果。后来我调整了基准有些并再次观察铸造 OfType 更快。

I ran an identical benchmark to Alex's and got the opposite result. I then tweaked the benchmark somewhat and again observed Cast being faster than OfType.

<击>没有太多的话,但我相信,演员确实有边缘​​,因为它应该,因为它的迭代器是简单。 (否支票。)

There's not much in it, but I believe that Cast does have the edge, as it should because its iterator is simpler. (No is check.)

<击>编辑:其实经过进一步的调整我管理要获得铸造是50倍比 OfType 更快。

下面是给我到目前为止发现的最大的差异基准的代码:

Below is the code of the benchmark that gives the biggest discrepancy I've found so far:

Stopwatch sw1 = new Stopwatch();
Stopwatch sw2 = new Stopwatch();

var ma = Enumerable.Range(1, 100000).Select(i => i.ToString()).ToArray();

var x = ma.OfType<string>().ToArray();
var y = ma.Cast<string>().ToArray();

for (int i = 0; i < 1000; i++)
{
    if (i%2 == 0)
    {
        sw1.Start();
        var arr = ma.OfType<string>().ToArray();
        sw1.Stop();
        sw2.Start();
        var arr2 = ma.Cast<string>().ToArray();
        sw2.Stop();
    }
    else
    {
        sw2.Start();
        var arr2 = ma.Cast<string>().ToArray();
        sw2.Stop();
        sw1.Start();
        var arr = ma.OfType<string>().ToArray();
        sw1.Stop();
    }
}
Console.WriteLine("OfType: " + sw1.ElapsedMilliseconds.ToString());
Console.WriteLine("Cast: " + sw2.ElapsedMilliseconds.ToString());
Console.ReadLine();



调整菜谱我做:

Tweaks I've made:


  • 执行生成的字符串列表工作的一次的,在一开始,和结晶吧。

  • 执行中的一个在开始计时每次运行前 - ?我不知道,如果这是必要的,但我认为这意味着抖动生成代码事前,而不是同时我们定时

  • 执行每一个操作多次,不只是一次。

  • 备用的情况下,这种有差别的顺序。

  • Perform the "generate a list of strings" work once, at the start, and "crystallize" it.
  • Perform one of each operation before starting timing - I'm not sure if this is necessary but I think it means the JITter generates code beforehand rather than while we're timing?
  • Perform each operation multiple times, not just once.
  • Alternate the order in case this makes a difference.

在我的机器的这导致〜350毫秒为铸造和〜为 OfType

On my machine this results in ~350ms for Cast and ~18000ms for OfType.

<击>我觉得最大的区别是,我们不再计时多久 MatchCollection 需要找到下一个匹配。 (或者说,在我的代码,多久 int.ToString()需要)。这大大降低了信噪比。

I think the biggest difference is that we're no longer timing how long MatchCollection takes to find the next match. (Or, in my code, how long int.ToString() takes.) This drastically reduces the signal-to-noise ratio.

编辑:正如sixlettervariables所指出的,这种巨大的差异的原因是,演员将短路而不用费心铸造,如果个别项目它可以投全的IEnumerable 。当我从使用 Regex.Matches 到一个数组,以避免测量正则表达式处理时间开机,我也转而使用一些强制转换为的IEnumerable<串> 并由此激活此短路。当我改变了我的基准,以禁用此短路,我得到的 轻微 的优势,以铸造,而不是 大规模 的之一。

As sixlettervariables pointed out, the reason for this massive difference is that Cast will short-circuit and not bother casting individual items if it can cast the whole IEnumerable. When I switched from using Regex.Matches to an array to avoid measuring the regex processing time, I also switched to using something castable to IEnumerable<string> and thus activated this short-circuiting. When I altered my benchmark to disable this short-circuiting, I get a slight advantage to Cast rather than a massive one.

这篇关于为什么OfType&LT;&GT;比演员LT更快;&GT ;?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆