Как увеличить скорость вычислений 500 000 строк? - C#

Узнай цену своей работы

Формулировка задачи:

Здравствуйте. Вопрос к людям с опытом. Как ускорить вычисления 500 000 строк. Задача посчитать, какую прибыль приносил магазин в среднем в день за месяц, т.е сумма прибыли за месяц / кол-во дней когда магазин работал. Имеется 600 магазинов, по которым получается список из более 20 000 строк (магазин, год, месяц), с продажами за день получается список из 500 000 строк (магазин, год, месяц, день, продажи). Результаты применение распараллеливания расчётов, оказались неудовлетворительным прирост в скорости на 30 сек. С 1600 сек (без многопоточности) до 1570 сек (многопоточность). А неудовлетворительны потому, что в ексэле такая операция при построении сводной таблицы занимает секунды. Вот и вопрос "Как ускорить вычисление?".
Листинг программы
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.IO;
  6. using System.Threading;
  7. using System.Threading.Tasks;
  8. namespace PohojMagaz
  9. {
  10. class Magazin : IEquatable<Magazin>
  11. {
  12. public Magazin(){}
  13. public Magazin(string NameStore, ushort Year, byte Month, DateTime dataTime, double SalesRub)
  14. {
  15. this.NameStore = NameStore;
  16. this.Year = Year;
  17. this.Month = Month;
  18. this.dataTime = dataTime;
  19. this.SalesRub = SalesRub;
  20. }
  21. public string NameStore { get; set; }
  22. public ushort Year { get; set; }
  23. public byte Month { get; set; }
  24. public DateTime dataTime = new DateTime();
  25. public double SalesRub { get; set; }
  26. public bool Equals(Magazin other)
  27. {
  28. //Check whether the compared object is null.
  29. if (Object.ReferenceEquals(other, null)) return false;
  30. //Check whether the compared object references the same data.
  31. if (Object.ReferenceEquals(this, other)) return true;
  32. //Check whether the products' properties are equal.
  33. return NameStore.Equals(other.NameStore) && Year.Equals(other.Year) && Month.Equals(other.Month) && dataTime.Equals(other.dataTime)
  34. && SalesRub.Equals(other.SalesRub);
  35. }
  36. // If Equals() returns true for a pair of objects
  37. // then GetHashCode() must return the same value for these objects.
  38. public override int GetHashCode()
  39. {
  40. //Get hash code for the Name field if it is not null.
  41. int hashMagazinNameStore = NameStore == null ? 0 : NameStore.GetHashCode();
  42. //Get hash code for the Code field.
  43. int hasMagazinYear = Year.GetHashCode();
  44. int hasMagazinMonth = Month.GetHashCode();
  45. int hasMagazindataTime = dataTime.GetHashCode();
  46. int hasMagazindataSalesRub = SalesRub.GetHashCode();
  47. //Calculate the hash code for the product.
  48. return hasMagazinYear ^ hashMagazinNameStore ^ hasMagazinMonth ^ hasMagazindataTime ^ hasMagazindataSalesRub;
  49. }
  50. }
  51. class Program
  52. {
  53. static void Main(string[] args)
  54. {
  55. Console.WriteLine("Чтение файла");
  56. List<Magazin> fail = new List<Magazin>();
  57. using (var str = new StreamReader("1.txt", Encoding.UTF8))
  58. {
  59. string s;
  60. int z = 0;
  61. while ((s = str.ReadLine()) != null)
  62. {
  63. z++;
  64. if (z > 1)
  65. {
  66. string[] sPod = s.Split('\t');
  67. fail.Add(new Magazin());
  68. fail.Last().NameStore = sPod[0];
  69. fail.Last().Year = Convert.ToUInt16(sPod[1]);
  70. fail.Last().Month = Convert.ToByte(sPod[2]);
  71. fail.Last().dataTime = Convert.ToDateTime(sPod[3]);
  72. fail.Last().SalesRub = sPod[4] == "" ? 0 : Convert.ToDouble(sPod[4].Replace(',','.'));
  73. }
  74. }
  75. }
  76.  
  77. // Получаем список магазинов для анализа
  78. List<string> nameStore = fail.Select(r => r.NameStore).Distinct().ToList();
  79. List<ushort> year = fail.Select(r => r.Year).Distinct().ToList();
  80. List<byte> month = fail.Select(r => r.Month).Distinct().ToList();
  81. Console.WriteLine("Убрать повторяющиеся");
  82. //Оставить уникальные значение (магазин, год, месяц)
  83. List<Magazin> storeAvgDey = new List<Magazin>();
  84. storeAvgDey = fail.AsParallel().Select(r => new Magazin(r.NameStore, r.Year, r.Month, new DateTime(), 0)).Distinct().ToList();
  85. //Рассчитываем какую прибыль приносил магазин, в среднем, в день за месяц
  86. Console.WriteLine("Расчёт среднего магазина");
  87. Parallel.ForEach(storeAvgDey, M =>
  88. {
  89. M.SalesRub =
  90. fail.AsParallel().Where(
  91. w =>
  92. w.NameStore == M.NameStore & w.Month == M.Month &
  93. w.Year == M.Year).Select(
  94. r => r.SalesRub).Average();
  95. });
  96. //Console.WriteLine("Поиск похожих магазинов");
  97. //Console.WriteLine("Вывод в файл");
  98. //using (var stream = new StreamWriter("Результат.txt"))
  99. //{
  100. //}
  101. Console.WriteLine("Готово");
  102. }
  103. }
  104. }

Решение задачи: «Как увеличить скорость вычислений 500 000 строк?»

textual
Листинг программы
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.IO;
  6. using System.Threading;
  7. using System.Threading.Tasks;
  8.  
  9. namespace PohojMagaz
  10. {
  11.     //Ключ пользовательского типа данных(несколько ключей Dictionary)
  12.     class Magazin : IEquatable<Magazin>
  13.     {
  14.         public Magazin(){}
  15.         public Magazin(string NameStore, ushort Year, byte Month)
  16.         {
  17.             this.NameStore = NameStore;
  18.             this.Year = Year;
  19.             this.Month = Month;
  20.         }
  21.         public string NameStore { get; set; }
  22.         public ushort Year { get; set; }
  23.         public byte Month { get; set; }
  24.  
  25.         public bool Equals(Magazin other)
  26.         {
  27.  
  28.             //Check whether the compared object is null.
  29.             if (Object.ReferenceEquals(other, null)) return false;
  30.  
  31.             //Check whether the compared object references the same data.
  32.             if (Object.ReferenceEquals(this, other)) return true;
  33.  
  34.             //Check whether the products' properties are equal.
  35.             return NameStore.Equals(other.NameStore) && Year.Equals(other.Year) && Month.Equals(other.Month);
  36.         }
  37.  
  38.         // If Equals() returns true for a pair of objects
  39.         // then GetHashCode() must return the same value for these objects.
  40.  
  41.         public override int GetHashCode()
  42.         {
  43.  
  44.             //Get hash code for the Name field if it is not null.
  45.             int hashMagazinNameStore = NameStore == null ? 0 : NameStore.GetHashCode();
  46.  
  47.             //Get hash code for the Code field.
  48.             int hasMagazinYear = Year.GetHashCode();
  49.             int hasMagazinMonth = Month.GetHashCode();
  50.  
  51.             //Calculate the hash code for the product.
  52.             return hasMagazinYear ^ hashMagazinNameStore ^ hasMagazinMonth;
  53.         }
  54.  
  55.     }
  56.     class Program
  57.     {
  58.        
  59.         static void Main(string[] args)
  60.         {
  61.             Console.WriteLine("Чтение файла");
  62.             Dictionary<Magazin,List<double>> fail = new Dictionary<Magazin, List<double>>();
  63.             using (var str = new StreamReader("1.txt", Encoding.UTF8))
  64.             {
  65.                 string s;
  66.                 int z = 0;
  67.                 while ((s = str.ReadLine()) != null)
  68.                 {
  69.                     z++;
  70.                     if (z > 1)
  71.                     {
  72.                         string[] sPod = s.Split('\t');
  73.                         Magazin temp = new Magazin(sPod[0], Convert.ToUInt16(sPod[1]), Convert.ToByte(sPod[2]));
  74.                         //Проверяем есть ли магазин из потока, если нет, то создаём магазин с List'ом
  75.                         if (!fail.Keys.Contains(temp))
  76.                         {
  77.                             fail.Add(
  78.                             temp,
  79.                             new List<double>());
  80.                             fail[temp].Add(sPod[4] == "" ? 0 : Convert.ToDouble(sPod[4]));
  81.                         }
  82.                         else fail[temp].Add(sPod[4] == "" ? 0 : Convert.ToDouble(sPod[4]));
  83.                     }
  84.                 }
  85.             }
  86.             //Convert.ToDouble(sPod[4].Replace(',', '.')
  87.            
  88.                 // Считаем средние продажи в день
  89.             Dictionary<Magazin, double> storeAvgDey = new Dictionary<Magazin, double>();
  90.             Console.WriteLine("Расчёт среднего магазина");
  91.             //При использовании параллельного ForEach происходит ошибка "Индекс находился вне границ массива."
  92.             //Parallel.ForEach(fail, M =>
  93.             //                           {
  94.             //                               storeAvgDey[M.Key] = M.Value.Average();
  95.             //                           });
  96.             foreach (var M in fail)
  97.             {
  98.                 storeAvgDey[M.Key] = M.Value.Average();
  99.             }
  100.  
  101.             Console.WriteLine("Поиск похожих магазинов");
  102.  
  103.             //Console.WriteLine("Вывод в файл");
  104.             //using (var stream = new StreamWriter("Результат.txt"))
  105.             //{
  106.  
  107.             //}
  108.             Console.WriteLine("Готово");
  109.         }
  110.     }
  111. }

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

13   голосов , оценка 4.385 из 5

Нужна аналогичная работа?

Оформи быстрый заказ и узнай стоимость

Бесплатно
Оформите заказ и авторы начнут откликаться уже через 10 минут
Похожие ответы