有什么好办法来表示一个IEnumerable是"缓慢"或QUOT;快"? [英] What is a good way to to indicate an IEnumerable is "slow" or "fast"?

查看:231
本文介绍了有什么好办法来表示一个IEnumerable是"缓慢"或QUOT;快"?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个问题的答案<一个href="http://stackoverflow.com/questions/10905297/what-is-the-expected-performance-of-ienumerable">What是的IEnumerable的业绩预期?说,有没有办法知道点儿关于迭代任意IEnumerable的表现。每次迭代可能达到一个数据库或进行网络serivce呼叫;或者它可能只是返回数组/列表中的下一个项目。

鉴于这种情况,有什么好办法来表示:这是快?例如, T [] 名单,其中,T&GT; 而不是的IEnumerable&LT; T&GT; 我知道,从 T [I] T [I + 1] 将要快点。 (当然,迫使枚举返回一个列表/阵列可以创建其他性能方面的问题名单,其中,T&GT; 也暴露出编辑语义)

相反,会返回的IQueryable&LT; T&GT; 而不是的IEnumerable&LT; T&GT; 是一个很好的方法来指示这就是慢?或者,也许的IEnumerable&LT;任务&LT; T&GT;&GT;

C

客户端没有办法knowning的是,的IEnumerable&LT; T&GT; 旨意有显着不同的性能特点

  C类
{
   只读T [] M_DATA;
   公开的IEnumerable&LT; T&GT; ThisWillIterateQuickly {{返回M_DATA; }}

   公共IEnumeralbe&LT; T&GT; ThisWillIterateSlowly
   {
      得到
      {
         牛逼RETVAL = ...昂贵的数据库调用...;
         得到的回报RETV​​AL;
      }
   }

   公众的IQueryable&LT; T&GT; IsThisBetterForSlow {{返回ThisWillIterateSlowly; }}
   大众T [] IsThisAGoodWayForFast {{返回M_DATA; }}
 }
 

解决方案

想着这一些之后,看来问题/问题实际上集中在的行为/性能IEnumerator.MoveNext()。使用的的Visual Studio 2012 的,我能创造的异步版本的IEnumerator 的IEnumerable

 公共接口IAsyncEnumerator&LT; T&GT; :IDisposable接口
{
    任务&LT; T&GT; CurrentAsync {获得; }
    任务&LT;布尔&GT; MoveNextAsync();
    任务ResetAsync();
}

公共接口IAsyncEnumerable&LT; T&GT;
{
    IAsyncEnumerator&LT; T&GT; GetAsyncEnumerator();
}
 

这种方法的缺点是没有很多的语言支持;上面会不会与的foreach 工作。但是,扩展方法可以缓解疼痛:

 公共静态类EnumeratorExtensions
{
    公共静态无效的ForEach&LT; T&GT;(这IEnumerable的&LT; T&GT;枚举,动作&LT; T&GT;动作)
    {
        使用(VAR枚举= enumerable.GetEnumerator())
        {
            而(enumerator.MoveNext())
                行动(enumerator.Current);
        }
    }

    公共静态异步任务ForEachAsync&LT; T&GT;(这IAsyncEnumerable&LT; T&GT;枚举,动作&LT; T&GT;动作)
    {
        使用(VAR枚举= enumerable.GetAsyncEnumerator())
        {
            同时,(等待enumerator.MoveNextAsync())
                行动(等待enumerator.CurrentAsync);
        }
    }
}
 

The answer to What is the expected performance of IEnumerable? says there's no way to know anyting about the performance of iterating an arbitrary IEnumerable. Each iteration could hit a database or make a web serivce call; or it might just return the next item in an array/list.

Given that, is there a good way to indicate "this is fast"? For example, with T[] or List<T> instead of IEnumerable<T> I know that going from T[i] to T[i+1] will be quick. (Of course, forcing the enumeration to return a list/array could create other performance concerns. List<T> also exposes editable semantics.)

Conversely, would returning IQueryable<T> instead of IEnumerable<T> be a good way to indicate "this is slow"? Or maybe IEnumerable<Task<T>>?

Clients of C have no way of knowning that the IEnumerable<T>s will have dramatically different performance characteristics.

class C
{
   readonly T[] m_data;
   public IEnumerable<T> ThisWillIterateQuickly { get { return m_data; } }

   public IEnumeralbe<T> ThisWillIterateSlowly
   {
      get
      {
         T retval = ... an expensive database call ...;
         yield return retval;
      }
   }

   public IQueryable<T> IsThisBetterForSlow { get { return ThisWillIterateSlowly; } }
   public T[] IsThisAGoodWayForFast { get { return m_data; } }
 }

解决方案

After thinking about this some more, it seems the problem/question really centers on the behavior/performance of IEnumerator.MoveNext(). Using Visual Studio 2012, I was able to create async versions of IEnumerator and IEnumerable:

public interface IAsyncEnumerator<T> : IDisposable
{
    Task<T> CurrentAsync { get; }
    Task<bool> MoveNextAsync();
    Task ResetAsync();
}

public interface IAsyncEnumerable<T>
{
    IAsyncEnumerator<T> GetAsyncEnumerator();
}

A disadvantage to this approach is there isn't a lot of language support; the above won't work with foreach. But, an extension method can ease the pain:

public static class EnumeratorExtensions
{
    public static void ForEach<T>(this IEnumerable<T> enumerable, Action<T> action)
    {
        using (var enumerator = enumerable.GetEnumerator())
        {
            while (enumerator.MoveNext())
                action(enumerator.Current);
        }
    }

    public static async Task ForEachAsync<T>(this IAsyncEnumerable<T> enumerable, Action<T> action)
    {
        using (var enumerator = enumerable.GetAsyncEnumerator())
        {
            while (await enumerator.MoveNextAsync())
                action(await enumerator.CurrentAsync);
        }
    }
}

这篇关于有什么好办法来表示一个IEnumerable是&QUOT;缓慢&QUOT;或QUOT;快&QUOT;?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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