using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Arrays
{
    class Examples16_18
    {
        // Listing 5-16
        public static int GetIndexOfFirstNonEmptyBin(int[] bins)
        {
            return Array.FindIndex(bins, value => value > 0);
        }

        // Listing 5-17
        public T[] GetNonNullItems<T>(T[] items) where T : class
        {
            return Array.FindAll(items, value => value != null);
        }


        private static void ComparePerf()
        {
            var sw = new Stopwatch();

            int[] big = new int[100000000];
            Console.WriteLine("Inicjalizacja danych");
            sw.Start();
            var r = new Random(0);
            for (int i = 0; i < big.Length; ++i)
            {
                big[i] = r.Next(big.Length);
            }
            sw.Stop();
            Console.WriteLine(sw.Elapsed.ToString("s\\.f"));
            Console.WriteLine();

            Console.WriteLine("Przeszukiwanie");
            for (int i = 0; i < 6; ++i)
            {
                int searchFor = r.Next(big.Length);
                sw.Reset();
                sw.Start();
                int index = Array.IndexOf(big, searchFor);
                sw.Stop();
                Console.WriteLine("Indeks: {0}", index);
                Console.WriteLine("Czas:  {0:s\\.ffff}", sw.Elapsed);
            }
            Console.WriteLine();

            Console.WriteLine("Sortowanie");
            sw.Reset();
            sw.Start();
            Array.Sort(big);
            sw.Stop();
            Console.WriteLine(sw.Elapsed.ToString("s\\.f"));
            Console.WriteLine();

            Console.WriteLine("Przeszukiwanie (binarne)");
            for (int i = 0; i < 6; ++i)
            {
                int searchFor = r.Next() % big.Length;
                sw.Reset();
                sw.Start();
                int index = Array.BinarySearch(big, searchFor);
                sw.Stop();
                Console.WriteLine("Indeks: {0}", index);
                Console.WriteLine("Czas:  {0:s\\.fffffff}", sw.Elapsed);
            }
        }

        public static void RunPerfComparison()
        {
            // Wykonajmy tę metodę kilka razy - pierwsze wywołanie będzie wolniejsze
            // ze względu na konieczność wykonania kompilacji JIT, a kolejne wykonanie
            // może być spowolnione przez inne operacje wykonywane przez komputer.

            ComparePerf();
            ComparePerf();
            ComparePerf();
            ComparePerf();
        }
    }
}
