Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is a good way to to indicate an IEnumerable is "slow" or "fast"?

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; } }
 }
like image 988
Ðаn Avatar asked Jun 07 '12 15:06

Ðаn


2 Answers

Conversely, would returning IQueryable instead of IEnumerable be a good way to indicate "this is slow"?

No, IQueryable<T> inherent from IEnumerable<T>... and the problem with IEnumerable<T>T is that it could be IQueryable<T> with a a huge side affect when iterating, like query a remote database or something like that.

Funny isn't it?

You probably should be asking about IEnumerable<T> V.S. List<T> which the second one definitely has the data in it, and doesn't need to get it from somewhere else.

like image 70
gdoron is supporting Monica Avatar answered Nov 05 '22 20:11

gdoron is supporting Monica


If you want to guarantee that iteration will not contain any surprises then I agree, expose a T[] - the enumerator for it cannot be overridden as you cannot inherit from arrays. Iteration is also side-effect free, the same cannot be said for IEnumerable<T>.

However, I would disagree that exposing an array expresses this message, which is more important (in my opinion). The performance of something can never really be expressed in code, unless you start naming stuff CheapIteration or ExpensiveIteration.

On the other side of the coin, with an array you simply move the performance problem of on-demand iteration to the point of populating the array. This is guaranteed to hit the performance problem fully as it will be a full iteration of whatever supplies the array contents. In an IEnumerable<T> if iteration stops, so does the performance problem - the fastest code is the code that doesn't run.

like image 23
Adam Houldsworth Avatar answered Nov 05 '22 22:11

Adam Houldsworth