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

问题描述

这个问题的答案What是的IEnumerable的业绩预期?说,有没有办法知道点儿关于迭代任意IEnumerable的表现。每次迭代可能达到一个数据库或进行网络serivce呼叫;或者它可能只是返回数组/列表中的下一个项目。

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

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

C

客户端没有办法knowning的是,的IEnumerable< T> 旨意有显着不同的性能特点

  C类
{
   只读T [] M_DATA;
   公开的IEnumerable< T> ThisWillIterateQuickly {{返回M_DATA; }}

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

   公众的IQueryable< T> IsThisBetterForSlow {{返回ThisWillIterateSlowly; }}
   大众T [] IsThisAGoodWayForFast {{返回M_DATA; }}
 }
 

解决方案

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

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

公共接口IAsyncEnumerable< T>
{
    IAsyncEnumerator< T> GetAsyncEnumerator();
}
 

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

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

    公共静态异步任务ForEachAsync< T>(这IAsyncEnumerable< T>枚举,动作< T>动作)
    {
        使用(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;?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-24 08:19