private static bool RunJoinTest1(int leftSize, int rightSize, int loops)
        {
            TestHarness.TestLog("RunJoinTest1({0}, {1}, {2})", leftSize, rightSize, loops);

            int[] left  = new int[leftSize];
            int[] right = new int[rightSize];

            for (int i = 0; i < left.Length; i++)
            {
                left[i] = i;
            }
            for (int i = 0; i < right.Length; i++)
            {
                right[i] = i * right.Length;
            }

            Func <int, int> identityKeySelector = delegate(int x) { return(x); };

            IEnumerable <Pair> seqQuery = Enumerable.Join <int, int, int, Pair>(
                left, right, identityKeySelector, identityKeySelector, delegate(int x, int y) { return(new Pair(x, y)); });
            ParallelQuery <Pair> parQuery = left.AsParallel().Join <int, int, int, Pair>(
                right.AsParallel(), identityKeySelector, identityKeySelector, delegate(int x, int y) { return(new Pair(x, y)); });

            PerfHelpers.DrivePerfComparison(
                delegate {
                Enumerable.ToList(seqQuery);
            },
                delegate {
                parQuery.ToList();
            },
                loops);

            return(true);
        }
        private static bool RunWeightedAverage1(int size, int loops)
        {
            TestHarness.TestLog("RunWeightedAverage1({0}, {1})", size, loops);

            long[] data = new long[size];
            for (int i = 0; i < size; i++)
            {
                data[i] = i + 1;
            }
            long[] weights = new long[size];
            for (int i = 0; i < size; i++)
            {
                weights[i] = 1 + (i % 20);
            }

            long presum = Enumerable.Sum(weights);

            PerfHelpers.DrivePerfComparison(
                delegate {
                double total = Enumerable.Sum(Enumerable.Select <long, long>(data, delegate(long x, int idx) { return(x * weights[idx]); }));
                double avg   = total / presum;  //Enumerable.Sum(weights);
            },
                delegate {
                double total = data.AsParallel().Zip <long, long, long>(weights.AsParallel(), (f, s) => f * s).Sum();
                double avg   = total / presum;  //;ParallelEnumerable.Sum(weights.AsParallel());
            },
                loops);

            return(true);
        }
        private static bool RunWhereTest2(int size, int loops)
        {
            int[] data = new int[size];

            for (int i = 0; i < data.Length; i++)
            {
                data[i] = i;
            }

            Func <int, int> identityKeySelector = delegate(int x) { return(x); };

            IEnumerable <int> seqQuery = Enumerable.Where <int>(data, delegate(int x) { object o = new object(); int xx = o.GetHashCode(); return((x % 2) == 0); });
            IEnumerable <int> parQuery = data.AsParallel().Where <int>(delegate(int x) { object o = new object(); int xx = o.GetHashCode(); return((x % 2) == 0); });

            PerfHelpers.DrivePerfComparison(
                delegate {
                foreach (int p in seqQuery)
                {
                    // Simulate some work:
                    object o1 = new object(); int xx1 = o1.GetHashCode();
                    object o2 = new object(); int xx2 = o1.GetHashCode();
                }
            },
                delegate {
                foreach (int p in parQuery)
                {
                    // Simulate some work:
                    object o1 = new object(); int xx1 = o1.GetHashCode();
                    object o2 = new object(); int xx2 = o1.GetHashCode();
                }
            },
                loops);

            return(true);
        }
        private static bool RunForAllTest1(int dataSize, int cycleCount, int loops)
        {
            TestHarness.TestLog("RunForAllTest1({0}, {1}, {2})", dataSize, cycleCount, loops);

            IEnumerable <int> data;

            {
                int[] arr = new int[dataSize];
                for (int i = 0; i < dataSize; i++)
                {
                    arr[i] = i;
                }
                data = arr;
            }

            PerfHelpers.DrivePerfComparison(
                delegate {
                foreach (int x in data)
                {
                    // Simulate N cycles of work:
                    SimulateCycles(x, cycleCount);
                }
            },
                delegate {
                data.AsParallel().ForAll(
                    delegate(int x)
                {
                    // Simulate N cycles of work:
                    SimulateCycles(x, cycleCount);
                });
            },
                loops);

            return(true);
        }
        //-----------------------------------------------------------------------------------
        // Exercises basic OrderBy behavior by sorting a fixed set of integers. They are fed
        // in already ascending, already descending, and random order for 3 variants.
        //

        private static bool RunOrderByTest1(int dataSize, bool descending, DataDistributionType type, int loops)
        {
            TestHarness.TestLog("RunOrderByTest1(dataSize = {0}, descending = {1}, type = {2})", dataSize, descending, type);

            int[] data = CreateOrderByInput(dataSize, type);

            IEnumerable <int>   seqQuery;
            ParallelQuery <int> parQuery;

            if (descending)
            {
                seqQuery = Enumerable.OrderByDescending <int, int>(data, delegate(int x) { return(x); }, System.Linq.Parallel.Util.GetDefaultComparer <int>());
                parQuery = data.AsParallel <int>().OrderByDescending <int, int>(
                    delegate(int x) { return(x); }, System.Linq.Parallel.Util.GetDefaultComparer <int>());
            }
            else
            {
                seqQuery = Enumerable.OrderBy <int, int>(data, delegate(int x) { return(x); }, System.Linq.Parallel.Util.GetDefaultComparer <int>());
                parQuery = data.AsParallel <int>().OrderBy <int, int>(
                    delegate(int x) { return(x); }, System.Linq.Parallel.Util.GetDefaultComparer <int>());
            }

            PerfHelpers.DrivePerfComparison(
                delegate { List <int> r = Enumerable.ToList <int>(seqQuery); },
                delegate { List <int> r = parQuery.ToList <int>(); },
                loops);

            return(true);
        }
        private static bool RunJoinTest3(int leftSize, int rightSize, int loops)
        {
            TestHarness.TestLog("RunJoinTest3({0}, {1}, {2})", leftSize, rightSize, loops);

            Wrapped <int>[] left  = new Wrapped <int> [leftSize];
            Wrapped <int>[] right = new Wrapped <int> [rightSize];

            for (int i = 0; i < left.Length; i++)
            {
                left[i] = new Wrapped <int>(i);
            }
            for (int i = 0; i < right.Length; i++)
            {
                right[i] = new Wrapped <int>(i * right.Length);
            }

            Func <Wrapped <int>, int> identityKeySelector = delegate(Wrapped <int> x) { return(x.val); };

            IEnumerable <Pair> seqQuery = Enumerable.Join <Wrapped <int>, Wrapped <int>, int, Pair>(
                left, right, identityKeySelector, identityKeySelector, delegate(Wrapped <int> x, Wrapped <int> y) { return(new Pair(x.val, y.val)); });
            IEnumerable <Pair> parQuery = left.AsParallel().Join <Wrapped <int>, Wrapped <int>, int, Pair>(
                right.AsParallel(), identityKeySelector, identityKeySelector, delegate(Wrapped <int> x, Wrapped <int> y) { return(new Pair(x.val, y.val)); });

            PerfHelpers.DrivePerfComparison(
                delegate {
                foreach (Pair p in seqQuery)
                {
                    // Simulate work:
                    int z = 0;
                    for (int i = 0; i < 5; i++)
                    {
                        z *= p.x;
                        z *= p.y;
                    }
                }
            },
                delegate {
                foreach (Pair p in parQuery)
                {
                    // Simulate work:
                    int z = 0;
                    for (int i = 0; i < 5; i++)
                    {
                        z *= p.x;
                        z *= p.y;
                    }
                }
            },
                loops);

            return(true);
        }
        private static bool RunMatrixMultTest(int m, int n, int o, int loops)
        {
            TestHarness.TestLog("RunMatrixMultTest(m={0}, n={1}, o={2}, loops={3})", m, n, o, loops);

            Random r = new Random(33); // same seed for predictable test results.

            // Generate our two matrixes out of random #s.

            int[,] m1 = new int[m, n];
            for (int i = 0; i < m; i++)
            {
                for (int j = 0; j < n; j++)
                {
                    m1[i, j] = r.Next(100);
                }
            }

            int[,] m2 = new int[n, o];
            for (int i = 0; i < n; i++)
            {
                for (int j = 0; j < o; j++)
                {
                    m2[i, j] = r.Next(100);
                }
            }

            PerfHelpers.DrivePerfComparison(
                delegate {
                int oldDop = System.Linq.Parallel.Scheduling.DefaultDegreeOfParallelism;
                System.Linq.Parallel.Scheduling.DefaultDegreeOfParallelism = 1;
                try {
                    var inner = ParallelEnumerable.Range(0, o);
                    int[] m3  = ParallelEnumerable.Range(0, m).
                                SelectMany(i => inner, (i, j) =>
                                           Enumerable.Range(0, n).Sum((k) => m1[i, k] * m2[k, j])).
                                ToArray();
                } finally {
                    System.Linq.Parallel.Scheduling.DefaultDegreeOfParallelism = oldDop;
                }
            },
                delegate {
                var inner = ParallelEnumerable.Range(0, o);
                int[] m3  = ParallelEnumerable.Range(0, m).
                            SelectMany(i => inner, (i, j) =>
                                       Enumerable.Range(0, n).Sum((k) => m1[i, k] * m2[k, j])).
                            ToArray();
            },
                loops);

            return(true);
        }
        private static bool RunWhereTest1(int size, int predSimulation, int workSimulation, int loops)
        {
            int[] data = new int[size];

            for (int i = 0; i < data.Length; i++)
            {
                data[i] = i;
            }

            Func <int, int> identityKeySelector = delegate(int x) { return(x); };

            IEnumerable <int> seqQuery = Enumerable.Where <int>(data, delegate(int x) { int xx = 1; for (int i = 0; i < predSimulation; i++)
                                                                                        {
                                                                                            xx *= (i + 1);
                                                                                        }
                                                                                        return((x % 2) == 0); });
            IEnumerable <int> parQuery = data.AsParallel().Where <int>(delegate(int x) { int xx = 1; for (int i = 0; i < predSimulation; i++)
                                                                                         {
                                                                                             xx *= (i + 1);
                                                                                         }
                                                                                         return((x % 2) == 0); });

            PerfHelpers.DrivePerfComparison(
                delegate {
                foreach (int p in seqQuery)
                {
                    // Simulate some work:
                    int z = 1;
                    for (int i = 0; i < workSimulation; i++)
                    {
                        z *= p;
                    }
                }
            },
                delegate {
                foreach (int p in parQuery)
                {
                    // Simulate some work:
                    int z = 1;
                    for (int i = 0; i < workSimulation; i++)
                    {
                        z *= p;
                    }
                }
            },
                loops);

            return(true);
        }
        private static bool RunJoinPlusWhereTest1(int leftSize, int rightSize, int loops)
        {
            TestHarness.TestLog("RunJoinPlusWhereTest1({0}, {1}, {2})", leftSize, rightSize, loops);

            int[] left  = new int[leftSize];
            int[] right = new int[rightSize];

            for (int i = 0; i < left.Length; i++)
            {
                left[i] = i;
            }
            for (int i = 0; i < right.Length; i++)
            {
                right[i] = i * right.Length;
            }

            Func <int, int> identityKeySelector = delegate(int x) { return(x); };

            IEnumerable <Pair> seqQuery = Enumerable.Join <int, int, int, Pair>(
                Enumerable.Where <int>(left, delegate(int x) { return((x % 2) == 0); }),
                right, identityKeySelector, identityKeySelector, delegate(int x, int y) { return(new Pair(x, y)); });
            IEnumerable <Pair> parQuery = left.AsParallel().Where <int>(delegate(int x) { return((x % 2) == 0); })
                                          .Join <int, int, int, Pair>(right.AsParallel(), identityKeySelector, identityKeySelector,
                                                                      delegate(int x, int y) { return(new Pair(x, y)); });

            PerfHelpers.DrivePerfComparison(
                delegate {
                foreach (Pair p in seqQuery)
                {
                    // Calc the log (to simulate some work):
                    Math.Log(p.x, p.y);
                }
            },
                delegate {
                foreach (Pair p in parQuery)
                {
                    // Calc the log (to simulate some work):
                    Math.Log(p.x, p.y);
                }
            },
                loops);

            return(true);
        }
        private static bool RunSumTest1(int size, int loops)
        {
            TestHarness.TestLog("RunSumTest1({0}, {1})", size, loops);

            int[] data = new int[size];
            for (int i = 0; i < data.Length; i++)
            {
                data[i] = i + 1;
            }

            PerfHelpers.DrivePerfComparison(
                delegate {
                double xx = Enumerable.Average(data);
                Debug.Assert(xx == (double)(size + 1) / 2);
            },
                delegate {
                double xx = data.AsParallel <int>().Average();
                Debug.Assert(xx == (double)(size + 1) / 2);
            },
                loops);

            return(true);
        }
        private static bool RunGroupWords1Test(int targetWords, int loops)
        {
            TestHarness.TestLog("RunGroupWords1Test(targetWords={0}, loops={1})", targetWords, loops);

            //@TODO: bundle data into a resource pack.
            string text = System.IO.File.ReadAllText("dat\\litpe10.txt");

            string[] split = text.Split(' ');
            string[] words = split;

            // If specific # of words desired, fill the buffer.
            if (targetWords != -1)
            {
                words = new string[targetWords];
                int last = 0;
                while (last < targetWords)
                {
                    Array.Copy(split, 0, words, last, Math.Min(split.Length, words.Length - last));
                    last += split.Length;
                }
            }

            TestHarness.TestLog("  (text length == {0}, words == {1})", text.Length, words.Length);

            PerfHelpers.DrivePerfComparison(
                delegate {
                var counts = from w in words group w by w;
                var force  = counts.ToList();
            },
                delegate {
                var counts = from w in words.AsParallel() group w by w;
                var force  = counts.ToList();
            },
                loops);

            return(true);
        }
        private static bool RunBicubicInterpolationTest(int m, int n, int loops)
        {
            TestHarness.TestLog("RunBicubicInterpolationTest(m={0}, n={1}, loops={2})", m, n, loops);

            Random r = new Random(33); // same seed for predictable test results.

            // Generate our image out of random #s.

            int[,] img = new int[m, n];
            for (int i = 0; i < m; i++)
            {
                for (int j = 0; j < n; j++)
                {
                    img[i, j] = r.Next(100);
                }
            }

            // Just pick some random weights.

            double[] bicubic_weights = new double[] {
                0.15, 0.25, 0.25, 0.15, 0.25, 0.5, 0.5, 0.25, 0.8,
                0.25, 0.5, 0.5, 0.25, 0.15, 0.25, 0.25, 0.15
            };
            ParallelQuery <double> W = bicubic_weights.AsParallel();

            PerfHelpers.DrivePerfComparison(
                delegate {
                // HACK: current version of LINQ doesn't have the right SelectMany
                // overload yet.  So we just compare to PLINQ w/ a DOP of 1 instead.
                int oldDop = System.Linq.Parallel.Scheduling.DefaultDegreeOfParallelism;
                System.Linq.Parallel.Scheduling.DefaultDegreeOfParallelism = 1;
                try {
                    double[] img2 = (
                        from x in ParallelEnumerable.Range(0, m)
                        from y in ParallelEnumerable.Range(0, n)
                        select
                            (from x2 in Enumerable.Range(m - 3, 7)
                            from y2 in Enumerable.Range(n - 3, 7)
                            where x2 >= 0 && x2 < m &&
                            y2 >= 0 && y2 < n &&
                            (x2 == x || (x2 - (m - 3) % 2) == 0) &&
                            (y2 == y || (y2 - (n - 3) % 2) == 0)
                            select img[x2, y2]
                            ).AsParallel().Zip(W, (i, j) => new Pair <int, double>(i, j)).Sum((p) => p.First * p.Second) / W.Sum()).ToArray();
                } finally {
                    System.Linq.Parallel.Scheduling.DefaultDegreeOfParallelism = oldDop;
                }
            },
                delegate {
                double[] img2 = (
                    from x in ParallelEnumerable.Range(0, m)
                    from y in ParallelEnumerable.Range(0, n)
                    select
                        (from x2 in Enumerable.Range(m - 3, 7)
                        from y2 in Enumerable.Range(n - 3, 7)
                        where x2 >= 0 && x2 < m &&
                        y2 >= 0 && y2 < n &&
                        (x2 == x || (x2 - (m - 3) % 2) == 0) &&
                        (y2 == y || (y2 - (n - 3) % 2) == 0)
                        select img[x2, y2]
                        ).AsParallel().Zip(W, (i, j) => new Pair <int, double>(i, j)).Sum((p) => p.First * p.Second) / W.Sum()).ToArray();
            },
                loops);

            return(true);
        }
        private static bool RunMatrixMultVsHandCodedTest(int m, int n, int o, int loops)
        {
            TestHarness.TestLog("RunMatrixMultVsHandCodedTest(m={0}, n={1}, o={2}, loops={3}) -- vs. hand coded parallel", m, n, o, loops);

            Random r = new Random(33); // same seed for predictable test results.

            // Generate our two matrixes out of random #s.

            int[,] m1 = new int[m, n];
            for (int i = 0; i < m; i++)
            {
                for (int j = 0; j < n; j++)
                {
                    m1[i, j] = r.Next(100);
                }
            }

            int[,] m2 = new int[n, o];
            for (int i = 0; i < n; i++)
            {
                for (int j = 0; j < o; j++)
                {
                    m2[i, j] = r.Next(100);
                }
            }

            PerfHelpers.DrivePerfComparison(
                delegate {
                int[,] m3 = new int[m, o];

                using (CountdownEvent latch = new CountdownEvent(Environment.ProcessorCount))
                {
                    int stride = m / Environment.ProcessorCount;
                    for (int _p = 0; _p < Environment.ProcessorCount; _p++)
                    {
                        int p = _p;
                        ThreadPool.QueueUserWorkItem(delegate {
                            int start = p * stride;
                            int end   = Math.Min((p + 1) * stride, m);
                            for (int i = start; i < end; i++)
                            {
                                for (int j = 0; j < o; j++)
                                {
                                    int s = 0;
                                    for (int k = 0; k < n; k++)
                                    {
                                        s += m1[i, k] * m2[k, j];
                                    }
                                    m3[i, j] = s;
                                }
                            }
                            latch.Signal();
                        });
                    }

                    latch.Wait();
                }
            },
                delegate {
                var inner = ParallelEnumerable.Range(0, o);
                int[] m3  = ParallelEnumerable.Range(0, m).
                            SelectMany(i => inner, (i, j) =>
                                       Enumerable.Range(0, n).Sum((k) => m1[i, k] * m2[k, j])).
                            ToArray();
            },
                loops);

            return(true);
        }