Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.67/6: Рейтинг темы: голосов - 6, средняя оценка - 4.67
1 / 1 / 0
Регистрация: 03.02.2012
Сообщений: 22

Как можно оптимизировать код?

10.07.2013, 12:41. Показов 1429. Ответов 9
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте, помогите пожалуйста ускорить работу программы.

Программа читает журнал событий винды, и выводит в gridControl.
На форме есть кнопка, при нажатии на которую создается элемент этого класса, а потом вызывается метод FilterAndShowEvents.
Этот класс отвечает за чтение и вывод журнала.

ListOfEvents - открывает журнал с указанным именем и переносит записи в список Log.
FilterAndShowEvents - удаляет записи с дублирующимися сообщениями, и заносит в gridControl.

Выполняется очень долго, подскажите что можно исправить.
Кликните здесь для просмотра всего текста
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Diagnostics;
 
 
namespace events
{
 
    class ListOfEvents
    {
        //Класс список событий
        //Конструктор открывает файл, и считывая строки создает записи типа EventLog, которые помещает в список
        //Метод FilterOfEvents отфильтровывает список, делая из множества записей об одном событии одну запись
        //Метод ShowInGridView запускает метод FilterOfEvents, чтобы неотфильтрованные записи не попали в gridView, переводит записи в тип Record, и указывает список из записей типа Record как DataSource GridControl'a
        public List<EventLogItem> Log;
 
        public ListOfEvents(string LogName, string MachineName, DevExpress.XtraEditors.ProgressBarControl progressbar1)
        {
            EventLog ev = new EventLog(LogName, MachineName);
            Log = new List<EventLogItem>();
            if (ev.Entries.Count > 0)
            {
                for (int i = 0; i < ev.Entries.Count; i++)
                {
                    Log.Add(new EventLogItem(ev.Entries[i]));
                    progressbar1.Position += 1;
                    progressbar1.Update();
                }
            }
            ev.Close();
        }
 
        public void FilterAndShowEvents(DevExpress.XtraGrid.Views.Grid.GridView gridView1, DevExpress.XtraGrid.GridControl gridControl1, DevExpress.XtraEditors.ProgressBarControl progressbar1)
        {
            gridView1.Columns.Clear();
            BindingList<EventRecord> listDataSource = new BindingList<EventRecord>();
 
            List<string> messages = new List<string>();//список сообщений
            for (int i = 0; i < Log.Count; i++)
            {
                messages.Add(Log[i].Message);
                progressbar1.Position += 1;
                progressbar1.Update();
            }
            messages = messages.Distinct().ToList();//список сообщений без  повторений
 
            //выбор групп с одинаковым сообщением, и помещение 1 элемента из каждой группы в отфильтрованный список
            for (int i = 0; i < messages.Count; i++)
            {
                List<EventLogItem> EventsWithCurrentMessage = Log.FindAll(
    delegate(EventLogItem el)
    {
        return el.Message == messages[i];
    }
    );  //лист всех событий с текущим сообщением
 
                EventLogItem elem = EventsWithCurrentMessage[0];
                if (elem != null)
                {
                    listDataSource.Add(new EventRecord(elem.MachineName,elem.DateTime,elem.Message,elem.Action));
                }
 
                Log.RemoveAll(
delegate(EventLogItem el)
{
    return el.Message == messages[i];
}
); // удалить из списка все события с уже отработанным сообщением
                progressbar1.Position += EventsWithCurrentMessage.Count;
                progressbar1.Update();
        }
 
            gridControl1.DataSource = listDataSource;
            //настройка ширины столбцов
            gridView1.Columns[0].Width = gridView1.CalcColumnBestWidth(gridView1.Columns[0]);
            gridView1.Columns[1].Width = gridView1.CalcColumnBestWidth(gridView1.Columns[1]);
            gridView1.Columns[2].Width = (gridView1.CalcColumnBestWidth(gridView1.Columns[2])) / 5;
            gridView1.Columns[3].Width = gridView1.CalcColumnBestWidth(gridView1.Columns[3]);
 
        }
 
    }
}

Для хранения единичной записи используется класс EventLogItem, а для занесения в таблицу EventRecord, но там нет ничего нагромажденного как здесь, так нечего улучшать, так что проблема в этом классе.

Добавлено через 2 часа 35 минут
Немного изменил метод FilterAndShowEvents , работает на 30 секунд быстрее, но все равно долго. Нынешняя версия выглядит так:
Кликните здесь для просмотра всего текста
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
     public void FilterAndShowEvents(DevExpress.XtraGrid.Views.Grid.GridView gridView1, DevExpress.XtraGrid.GridControl gridControl1, DevExpress.XtraEditors.ProgressBarControl progressbar1)
        {
            gridView1.Columns.Clear();
            BindingList<EventRecord> listDataSource = new BindingList<EventRecord>();
 
            //выбор групп с одинаковым сообщением, и помещение 1 элемента из каждой группы в отфильтрованный список
            for (int i = 0; i < Log.Count; i++)
            {
                List<EventLogItem> EventsWithCurrentMessage = Log.FindAll(
    delegate(EventLogItem el)
    {
        return el.Message == Log[i].Message;
    }
    );  //лист всех событий с текущим сообщением
 
                EventLogItem elem = EventsWithCurrentMessage[0];
                if (elem != null)
                {
                    listDataSource.Add(new EventRecord(elem.MachineName,elem.DateTime,elem.Message,elem.Action));
                }
 
                Log.RemoveAll(
delegate(EventLogItem el)
{
    return el.Message == Log[i].Message;
}
); // удалить из списка все события с уже отработанным сообщением
                i = 0;
                progressbar1.Position += EventsWithCurrentMessage.Count;
                progressbar1.Update();
        }
 
            gridControl1.DataSource = listDataSource;
            //настройка ширины столбцов
            gridView1.Columns[0].Width = gridView1.CalcColumnBestWidth(gridView1.Columns[0]);
            gridView1.Columns[1].Width = gridView1.CalcColumnBestWidth(gridView1.Columns[1]);
            gridView1.Columns[2].Width = (gridView1.CalcColumnBestWidth(gridView1.Columns[2])) / 5;
            gridView1.Columns[3].Width = gridView1.CalcColumnBestWidth(gridView1.Columns[3]);
 
        }
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
10.07.2013, 12:41
Ответы с готовыми решениями:

Подскажите, как можно оптимизировать код?
Код проверяет, что нет такого ид в переменной for (int i = 0; c33 &lt; cd1.Split(';').Length; i++) { ...

Можно ли оптимизировать приведенный код
Понимаю, что нужно создать ещё одно измерение массива, но боюсь, что я уже и в этом запутался. ... byte mac10 = new...

Насколько можно оптимизировать этот программный код?
static void Main(string args) { int massiv1 = new int; Random rand = new Random(); int...

9
Master of Orion
Эксперт .NET
 Аватар для Psilon
6102 / 4958 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
10.07.2013, 13:56
Запустить профайлер, он подскажет, какой конкретно метод исправлять, только он и нужен нам)
1
1 / 1 / 0
Регистрация: 03.02.2012
Сообщений: 22
10.07.2013, 14:46  [ТС]
Спасибо за совет, но я уже в программу встроил таймер чтобы смотреть что да как.
Убрал все, что можно было безболезненно убрать, работает гораздо быстрее, осталось убрать/заменить один кусок кода и все.
Подскажите чем менее затратным можно заменить вот эту часть?
C#
1
2
3
4
5
6
Log.RemoveAll(
delegate(EventLogItem el)
{
    return ((el.Message == Log[i].Message)&&(el.DateTime==Log[i].DateTime));
}
);;
она находится в цикле, и поэтому вызывается много раз. Там суть в том, что из всех событий с определенным сообщением и временем нужно добавить только одно, все остальные удалить.

Я подумал, что гораздо лучше будет удалить дубликаты из списка до цикла методом Distinct(), но он работает для просто списков, а не для списка классов. Вы не знаете, можно ли как-нибудь применить его к такому списку?
0
Master of Orion
Эксперт .NET
 Аватар для Psilon
6102 / 4958 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
10.07.2013, 14:57
ObiomoFF, логику словами опишите.

А профайлер с таймером сравнивать все равно, что полноценный дебаггер с отладочной печатью
0
52 / 45 / 4
Регистрация: 07.10.2010
Сообщений: 95
10.07.2013, 15:10
C#
1
public List<EventLogItem> Log;
переделать на какой то
C#
1
Dictionary<string, List<EventLogItem>> a
Log.FindAll Log.RemoveAll переделать на работу с ключем Dictionary.
0
1 / 1 / 0
Регистрация: 03.02.2012
Сообщений: 22
11.07.2013, 07:18  [ТС]
Сделал свой Comparer для класса, как написано вот здесь http://msdn.microsoft.com/en-u... s.90).aspx, стало гораздо быстрее работать.

Но работа с прогрессбаром занимает очень много времени.
У меня в метод передается прогресс бар, и там в циклах увеличиваю позицию на 1.Может его можно как-нибудь оптимальнее выполнить?
0
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
11.07.2013, 11:31
Цитата Сообщение от ObiomoFF Посмотреть сообщение
Но работа с прогрессбаром занимает очень много времени.
У меня в метод передается прогресс бар, и там в циклах увеличиваю позицию на 1.Может его можно как-нибудь оптимальнее выполнить?
Обновляйте прогресс не каждую итерацию, а каждые 10, например.
Еще лучше, заведите 2 переменных и один таймер с интервалом 100мс: в переменных храните общее количество записей и обработанное количество. А по тику таймера высчитывайте из этих переменных прогресс и обновляйте интерфейс (10 раз в секунду — более чем достаточно для оконного приложения).
1
1 / 1 / 0
Регистрация: 03.02.2012
Сообщений: 22
11.07.2013, 12:14  [ТС]
kolorotur, спасибо за совет, сделал обновление каждый сотый раз, работает гораздо быстрее.
0
Master of Orion
Эксперт .NET
 Аватар для Psilon
6102 / 4958 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
11.07.2013, 13:58
ObiomoFF, сделайте обновление не каждый сотый раз, а каждые 100мс, ускорите еще намного )
0
 Аватар для Энтомолог
141 / 182 / 44
Регистрация: 25.04.2012
Сообщений: 2,623
Записей в блоге: 5
11.07.2013, 17:35
Можно попробовать создать
C#
1
List<Thread>
и в него отправлять все запуски этого
C#
1
2
3
4
5
6
 Log.RemoveAll(
delegate(EventLogItem el)
{
    return el.Message == Log[i].Message;
}
);
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
11.07.2013, 17:35
Помогаю со студенческими работами здесь

Как оптимизировать код?
Всем добрый день) Недавно начал изучать C# и решил написать такую программу: В 50-х годах XX века был предложен (к сожалению,...

Как оптимизировать код?
Подскажите пожалуйста, как в данном коде избавиться от необходимости каждый раз перед тригонометрическими методами прописывать название...

Подскажите как оптимизировать код
Собственно вот... void CalcValue(dynamic e) { var rez = e.GetType(); if (rez.Name ==...

Как оптимизировать код ввода из консоли?
Простите, возможна как-нибудь оптимизировать?

Можно ли, и если можно то как перевести код SQL в код С#
КОД ПРОГРАММЫ void __fastcall TForm1::SKChange(TObject *Sender) //Выбор таблицы { Table1-&gt;Active=false; ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
Новые блоги и статьи
Символические и жёсткие ссылки в Linux.
algri14 15.03.2026
Существует два типа ссылок — символические и жёсткие. Ссылка в Linux — это дополнительная запись в каталоге, которая может указывать либо на inode «файла-ИСТОЧНИКА», тогда это будет «жёсткая. . .
[Owen Logic] Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора
ФедосеевПавел 14.03.2026
Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора ВВЕДЕНИЕ Выполняя задание на управление насосной группой заполнения резервуара,. . .
делаю науч статью по влиянию грибов на сукцессию
anaschu 13.03.2026
прикрепляю статью
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru