Я работаю над разделом проекта, в котором используется большое количество методов суммирования. Эти методы суммирования применяются к таблице данных
Чтобы проверить лучший метод, я использую следующую
структуру таблицы данных
class LogParser
{
public DataTable PGLStat_Table = new DataTable();
public LogParser()
{
PGLStat_Table.Columns.Add("type", typeof(string));
PGLStat_Table.Columns.Add("desc", typeof(string));
PGLStat_Table.Columns.Add("count", typeof(int));
PGLStat_Table.Columns.Add("duration", typeof(decimal));
PGLStat_Table.Columns.Add("cper", typeof(decimal));
PGLStat_Table.Columns.Add("dper", typeof(decimal));
PGLStat_Table.Columns.Add("occurancedata", typeof(string));
}
}
Следующий метод используется для заполнения таблицы
LogParser pglp = new LogParser();
Random r2 = new Random();
for (int i = 1; i < 1000000; i++)
{
int c2 = r2.Next(1, 1000);
pglp.PGLStat_Table.Rows.Add("Type" + i.ToString(), "desc" + i , c2, 0, 0, 0, " ");
}
Следующие методы, используемые для вычисления суммы
Метод 1 с использованием Compute
Stopwatch s2 = new Stopwatch();
s2.Start();
object sumObject;
sumObject = pglp.PGLStat_Table.Compute("Sum(count)", " ");
s2.Stop();
long d1 = s2.ElapsedMilliseconds;
Метод 2 с использованием цикла Foreach
s2.Restart();
int totalcount = 0;
foreach (DataRow dr in pglp.PGLStat_Table.Rows)
{
int c = Convert.ToInt32(dr["count"].ToString());
totalcount = totalcount + c;
}
s2.Stop();
long d2 = s2.ElapsedMilliseconds;
Метод 3 с использованием Linq
s2.Restart();
var sum = pglp.PGLStat_Table.AsEnumerable().Sum(x => x.Field<int>("count"));
MessageBox.Show(sum.ToString());
s2.Stop();
long d3 = s2.ElapsedMilliseconds;
После сравнения результаты
a) foreach — это самое быстрое 481 мс
b) затем linq 1016 мс
c) а затем вычисление 2253 мс
Запрос 1
Я случайно изменил «c2 на i» в следующем операторе
pglp.PGLStat_Table.Rows.Add("Type" + i.ToString(), "desc" + i , i, 0, 0, 0, " ");
Оператор Linq выдает ошибку
Арифметическая операция привела к переполнению.
Принимая во внимание, что цикл Compute и Foreach по-прежнему может завершить вычисление, хотя и может быть некорректным.
Является ли такое поведение поводом для беспокойства или я пропустил директиву? (также вычисленные цифры велики)
Запрос 2
У меня сложилось впечатление, что Linq делает это быстрее всего, есть ли оптимизированный метод или параметр что заставляет его работать лучше.
спасибо за совет
arvind