You were given a task to shop for a component you cannot make by yourself, say fibonacci number generators.
You found two vendors. Both of their components produces correct output, both of them can generate up to fifty fibonaccis, and both of them are priced the same.
All things being equal, you are left with one qualifier, a good qualifier, you want to choose the component with a better quality. But for some reasons, these two vendors don't want to give you their source codes, hence you cannot see how they implement things. They just want to give you the DLL only.
But those vendors still have some kindness left in their hearts, they at least give you a clue how their components work.
Vendor A told you they uses eager loading(i.e. uses IList)
Vendor B told you they uses lazy loading(i.e. uses yield return)
In case like this, you need to purchase vendor B's component.
Vendor A's approach uses too much memory, they put elements to an allocated memory. Vendor B generates elements on-the-fly.
Desirability of vendor B's approach is more apparent if for example you just want the 8th fibonacci.
Using vendor A's component, your code still need to wait a long time in order to get the 8th element. Why it is so? Even you just want the 8th element, your code still need for vendor A's component to generate the whole 50 elements, after doing so, then that's the only time you can pick the 8th element.
Using vendor B's component, if you just want to get the 8th element, it will stop generating on the 8th element. Your code don't need vendor B's component to generate all the 50 elements in order for your code to get the 8th element. Vendor B's component has some smart on it.
To contrast the difference between IList and yield return, check the output of this code:
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ChooseLesserOfTheTwoEvils { class Program { static void Main(string[] args) { TestLoopOnEvilA(); Console.WriteLine("------"); TestLoopOnEvilB(); Console.WriteLine("------"); Console.ReadKey(); TestPick8thOnEvilA(); Console.WriteLine("------"); TestPick8thOnEvilB(); Console.WriteLine("------"); Console.ReadKey(); } static void TestPick8thOnEvilA() { Console.WriteLine("TestPick8thOnEvilA"); long eighth = EvilCompanyA.MathProvider.Fibonacci().Skip(7).Take(1).Single(); Console.WriteLine("\nEvil A's 8th fibonacci is {0}", eighth); } static void TestPick8thOnEvilB() { Console.WriteLine("TestPick8thOnEvilB"); long eighth = EvilCompanyB.MathProvider.Fibonacci().Skip(7).Take(1).Single(); Console.WriteLine("\nEvil B's 8th fibonacci is {0}", eighth); } static void TestLoopOnEvilA() { Console.WriteLine("Test Loop On Evil A"); IEnumerable<long> bucket = EvilCompanyA.MathProvider.Fibonacci(); Console.WriteLine("\nTest start"); foreach (var item in bucket) { Console.WriteLine("Evil A's Fib: {0}", item); } Console.ReadLine(); } static void TestLoopOnEvilB() { Console.WriteLine("Test Loop On Evil B"); IEnumerable<long> bucket = EvilCompanyB.MathProvider.Fibonacci(); Console.WriteLine("\nTest start"); foreach (var item in bucket) { Console.WriteLine("Evil B's Fib: {0}", item); } Console.ReadLine(); } } } namespace EvilCompanyA { public static class MathProvider { public static IEnumerable<long> Fibonacci() { IList<long> il = new List<long>(); long a = 0, b = 1; for (int i = 1; i <= 50; ++i) { Console.Write("eager{0} ",i); il.Add(a); long n = a; a += b; b = n; } return il; } } } namespace EvilCompanyB { public static class MathProvider { public static IEnumerable<long> Fibonacci() { long a = 0, b = 1; for (int i = 1; i <= 50; ++i) { Console.Write("lazy{0} ",i); yield return a; long n = a; a += b; b = n; } } } }
Output:
Test Loop On Evil A eager1 eager2 eager3 eager4 eager5 eager6 eager7 eager8 eager9 eager10 eager11 eager12 eager13 eager14 eager15 eager16 eager17 eager18 eager19 eager20 eager21 eager22 eager23 eager24 eager25 eager26 eager27 eager28 eager29 eager30 eager31 eager32 eager33 eager34 eager35 eager36 eager37 eager38 eager39 eager40 eager41 eager42 eager43 eager44 eager45 eager46 eager47 eager48 eager49 eager50 Test start Evil A's Fib: 0 Evil A's Fib: 1 Evil A's Fib: 1 Evil A's Fib: 2 Evil A's Fib: 3 Evil A's Fib: 5 Evil A's Fib: 8 Evil A's Fib: 13 Evil A's Fib: 21 Evil A's Fib: 34 Evil A's Fib: 55 Evil A's Fib: 89 Evil A's Fib: 144 Evil A's Fib: 233 Evil A's Fib: 377 Evil A's Fib: 610 Evil A's Fib: 987 Evil A's Fib: 1597 Evil A's Fib: 2584 Evil A's Fib: 4181 Evil A's Fib: 6765 Evil A's Fib: 10946 Evil A's Fib: 17711 Evil A's Fib: 28657 Evil A's Fib: 46368 Evil A's Fib: 75025 Evil A's Fib: 121393 Evil A's Fib: 196418 Evil A's Fib: 317811 Evil A's Fib: 514229 Evil A's Fib: 832040 Evil A's Fib: 1346269 Evil A's Fib: 2178309 Evil A's Fib: 3524578 Evil A's Fib: 5702887 Evil A's Fib: 9227465 Evil A's Fib: 14930352 Evil A's Fib: 24157817 Evil A's Fib: 39088169 Evil A's Fib: 63245986 Evil A's Fib: 102334155 Evil A's Fib: 165580141 Evil A's Fib: 267914296 Evil A's Fib: 433494437 Evil A's Fib: 701408733 Evil A's Fib: 1134903170 Evil A's Fib: 1836311903 Evil A's Fib: 2971215073 Evil A's Fib: 4807526976 Evil A's Fib: 7778742049 ------ Test Loop On Evil B Test start lazy1 Evil B's Fib: 0 lazy2 Evil B's Fib: 1 lazy3 Evil B's Fib: 1 lazy4 Evil B's Fib: 2 lazy5 Evil B's Fib: 3 lazy6 Evil B's Fib: 5 lazy7 Evil B's Fib: 8 lazy8 Evil B's Fib: 13 lazy9 Evil B's Fib: 21 lazy10 Evil B's Fib: 34 lazy11 Evil B's Fib: 55 lazy12 Evil B's Fib: 89 lazy13 Evil B's Fib: 144 lazy14 Evil B's Fib: 233 lazy15 Evil B's Fib: 377 lazy16 Evil B's Fib: 610 lazy17 Evil B's Fib: 987 lazy18 Evil B's Fib: 1597 lazy19 Evil B's Fib: 2584 lazy20 Evil B's Fib: 4181 lazy21 Evil B's Fib: 6765 lazy22 Evil B's Fib: 10946 lazy23 Evil B's Fib: 17711 lazy24 Evil B's Fib: 28657 lazy25 Evil B's Fib: 46368 lazy26 Evil B's Fib: 75025 lazy27 Evil B's Fib: 121393 lazy28 Evil B's Fib: 196418 lazy29 Evil B's Fib: 317811 lazy30 Evil B's Fib: 514229 lazy31 Evil B's Fib: 832040 lazy32 Evil B's Fib: 1346269 lazy33 Evil B's Fib: 2178309 lazy34 Evil B's Fib: 3524578 lazy35 Evil B's Fib: 5702887 lazy36 Evil B's Fib: 9227465 lazy37 Evil B's Fib: 14930352 lazy38 Evil B's Fib: 24157817 lazy39 Evil B's Fib: 39088169 lazy40 Evil B's Fib: 63245986 lazy41 Evil B's Fib: 102334155 lazy42 Evil B's Fib: 165580141 lazy43 Evil B's Fib: 267914296 lazy44 Evil B's Fib: 433494437 lazy45 Evil B's Fib: 701408733 lazy46 Evil B's Fib: 1134903170 lazy47 Evil B's Fib: 1836311903 lazy48 Evil B's Fib: 2971215073 lazy49 Evil B's Fib: 4807526976 lazy50 Evil B's Fib: 7778742049 ------ TestPick8thOnEvilA eager1 eager2 eager3 eager4 eager5 eager6 eager7 eager8 eager9 eager10 eager11 eager12 eager13 eager14 eager15 eager16 eager17 eager18 eager19 eager20 eager21 eager22 eager23 eager24 eager25 eager26 eager27 eager28 eager29 eager30 eager31 eager32 eager33 eager34 eager35 eager36 eager37 eager38 eager39 eager40 eager41 eager42 eager43 eager44 eager45 eager46 eager47 eager48 eager49 eager50 Evil A's 8th fibonacci is 13 ------ TestPick8thOnEvilB lazy1 lazy2 lazy3 lazy4 lazy5 lazy6 lazy7 lazy8 Evil B's 8th fibonacci is 13 ------
Live Code: http://ideone.com/QxU7Sn
No comments:
Post a Comment