Проблема заключается в том, что моя программа не может справится со своей задачей, слишком много данных проходит один поток данных.
Пример моего кода:
// Высчитывание формул для второй таблицы (и сразу записываем)
for (int i = 0; i < dataGridView1.RowCount - 1; i++)
{
if (this.dataGridView2.CurrentRow != null)
{
dataGridView2.Rows.Add();
//первый пример
this.dataGridView2.Rows[i].Cells[0].Value += string.Format("{0:0.###}", Convert.ToDouble((Convert.ToDouble(dataGridView1[2, i].Value) - Convert.ToDouble(dataGridView1[2, 0].Value)) * Convert.ToDouble(textBox1.Text)));
//второй пример
this.dataGridView2.Rows[i].Cells[1].Value += string.Format("{0:0.#####}", Convert.ToDouble((Convert.ToDouble(dataGridView1[7, i].Value) - Convert.ToDouble(dataGridView1[7, 0].Value)) / 78));
//делаем расчёты дополнительных величин
double poin = Convert.ToDouble((from DataGridViewRow row in dataGridView2.Rows
where row.Cells[3].FormattedValue.ToString() != string.Empty
select Convert.ToDouble(row.Cells[3].FormattedValue)).Max().ToString());
}
else
{
i--;
dataGridView2.Rows.RemoveAt(i);
return;
}
}
У меня есть только две идеи как ускорить код:
но проблема в том, что я никогда не сталкивался с этим и даже представления не имею как их сюда привинтить... В интернете я видел обучения на примере (MyWebService)
На данный момент программа виснет (если много данных обрабатывает), но при этом же процессор нагружен только на 6% (и то 3-4% это посторонние программы) и оперативная память загружается только, когда программа выполнит свою задачу.
Я любитель иногда пострадать... кхм... фигнёй. Поэтому держите ваш код с микрооптимизациями:
double d = Convert.ToDouble(textBox1.Text);
for (int i = 0; i < dataGridView1.RowCount - 1; i++)
{
var cells = dataGridView2.Rows[i].Cells;
if (dataGridView2.CurrentRow != null)
{
dataGridView2.Rows.Add();
cells[0].Value +=
((Convert.ToDouble(dataGridView1[2, i].Value) - Convert.ToDouble(dataGridView1[2, 0].Value)) * d)
.ToString("0.###");
cells[1].Value +=
((Convert.ToDouble(dataGridView1[7, i].Value) - Convert.ToDouble(dataGridView1[7, 0].Value)) / 78)
.ToString("0.#####");
double poin = (from DataGridViewRow row in dataGridView2.Rows
where row.Cells[3].FormattedValue.ToString() != string.Empty
select Convert.ToDouble(row.Cells[3].FormattedValue)).Max();
}
else
{
dataGridView2.Rows.RemoveAt(i - 1);
return;
}
}
Что сделано: я обратил внимание, что конвертация Convert.ToDouble(textBox1.Text)
выполняется многократно в цикле. Вынес это за цикл.
Ввёл переменную cells
. Не ради перфоманса, а ради сокращения кода.
Убрал все лишние вызовы Convert.ToDouble
. В том числе из linq-запроса.
Заменил string.Format
на ToString
. Метод форматирования в рантайме парсит свою строку формата и ищет места подстановки параметров. Из-за этого его производительность весьма печальна.
Примечание: у датагрида и его ячеек есть свойство DataGridViewCell.Style. Можно задать его свойство Format и не нужно будет делать форматирование в коде.
Это всё должно улучшить производительность (но совсем чуть-чуть, конечно же).
Выражение row.Cells[3].FormattedValue.ToString() != string.Empty
вероятно можно заменить на row.Cells[3].FormattedValue != null
. Это будет быстрее, но нужно точно знать, что там у вас может быть.
Если бы осуществлялась привязка типизированной коллекции (со свойствами типа double), то вызовы Convert.ToDouble
можно было бы заменить на приведение типа:
(((double)dataGridView1[7, i].Value - (double)dataGridView1[7, 0].Value) / 78)
Это тоже было бы быстрее.
Но в любом случае, это микрооптимизации.
Применить распараллеливание к этому коду напрямую невозможно, т. к. он работает с GUI-контролами. А менять их состояние из другого потока нельзя. Ставить вызовы Control.Invoke
и т. п. - убить весь эффект от параллельности.
Поэтому самый правильный выход - не работать с GUI. Как вам уже советовали в комментариях и другом ответе, храните данные в типизированных коллекцих: List<T>
, например. Код сразу станет быстрее и проще, без всех этих конвертаций. И прикрутить параллельность - раз плюнуть.
Первое, что я бы посоветовал, это разделить логику и представление данных. Сейчас они у Вас слиты воедино (тот же dataGridView
используется для хранения и манипулирования данными). Думаю, что когда визуальные компоненты будут использоваться только для отображения готовых данных Вы уже получите немалую выгоду по ресурсам.
А, дальше уже нужно смотреть вычислительную сложность алгоритма, асинхронность/распараллеливание и т.д.
слишком много данных проходит один поток данных.
. . .
У меня есть только две идеи как упростить код:
Через Async или AWait Через много поточность
И то и другое само по себе может избавить Вас от блокировки ("зависания") пользовательского интерфейса, при обработке большого объёма информации (если всё сделаете правильно). С эффективностью алгоритмов и распределением вычислений по потокам Вам нужно будет уже самому разбираться.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Всем привет, если в браузере вставить ссылку на канал https://tme/durov, то при условии если установлен телеграм, то вы автоматически перейдете на этот...
В WPF/MVVM игре есть модель часов, которые изменяются каждую секундуА в другой модели описаны свойства игрока - голод и усталость
При выключении панели (метод Hide): включить анимацию, дождаться завершения анимации, а только потом выключать объект (методом SetActive(false))Event...
Простой контроллер на выход из учетной записи