powered by simpleCommunicator - 2.0.55     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Как ускорить работу кода?
25 сообщений из 27, страница 1 из 2
Как ускорить работу кода?
    #38690946
SNenko
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Существует проект(написан еще до меня на C#).
загружается фотография(работает фоном).
По размеру фотографии поелементно создается матрица 20x20 из UserControl-компонентов.

на компоненте:
public System.Windows.Forms.Panel pnMain;
public System.Windows.Forms.Label lblText;

Очень долго загружается(у меня проц і5, а на производстве вообще мрак)

Как ускорить работу кода?
Можно переписать код, но принцып изменить немугу, там завязано много на этот принцып.
Код процедуры:
Код: 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.
public static void CreateSections(PictureBox pbMain, IDictionary<string, string> dic, int cellCountRows = 20, int cellCountColumns =20 ) {
	Size sz = getZoomedImage(pbMain);

	double width = sz.Width;
	double height = sz.Height;

	if (width % 10 > 0)
		width = Math.Round(width / 10) * 10;

	if (height % 10 > 0)
		height = Math.Round(height / 10) * 10;

	float widthOneComponent = sz.Width / cellCountColumns;
	float heightOneComponent = sz.Height / cellCountRows;

	int v_begin = (pbMain.ClientSize.Height - sz.Height) / 2;
	int h_begin = (pbMain.ClientSize.Width - sz.Width) / 2;

	int v = v_begin;
	int h = h_begin;
	
	int number = 1;
	pbMain.Visible = false;

	while ((v + heightOneComponent - (heightOneComponent / 2)) < (height + v_begin)) {
		
		while ((h + widthOneComponent - (widthOneComponent / 2)) < (width + h_begin)) {
			Cell r = new Cell();
			r.Name = "VisComponent" + number;
			r.Top = v;
			r.Left = h;
			r.Height = Convert.ToInt32(heightOneComponent);
			r.Width = Convert.ToInt32(widthOneComponent);

			r.pnMain.Click += delegate(object o, EventArgs e) {
				using (SqlConnection con = new SqlConnection(ConnStr)) {
					r.lblText.Visible = true;
					r.lblText.ForeColor = Color.Red;
					r.lblText.BackColor = Color.Red;

					con.Open();
					string sql = " insert into tbl_Transaction(AssmID, Position, LastUpdate) " +
									" values(@AssmID, @Position, GETDATE()) ";
					using (SqlCommand com = new SqlCommand(sql, con)) {
						com.Parameters.Add("@AssmID", dic["id"]);
						com.Parameters.Add("@Position", r.lblText.Text);
						com.ExecuteNonQuery();
					}
				}

				System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();
				timer.Interval = 1000;
				timer.Tick += (source, u) => { r.lblText.Visible = false; timer.Stop(); };
				timer.Start();
			};

			r.BorderStyle = BorderStyle.None;
			r.lblText.Text = number.ToString();
			r.lblText.Left = 0;
			r.lblText.Top = 0;
			r.lblText.ForeColor = Color.White;
			r.lblText.BackColor = Color.Black;
			r.lblText.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
			//-----
			r.lblText.Visible = false;

			pbMain.Controls.Add(r);

			number += 1;
			h += Convert.ToInt32(widthOneComponent);
		}
		
		v += Convert.ToInt32(heightOneComponent);
		h = 0;
		
	}

	pbMain.Visible = true;
}


Спасибо за внимание!
...
Рейтинг: 0 / 0
Как ускорить работу кода?
    #38691005
Фотография buser
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
нечего тут оптимизировать... может ежли только не pbMain.Controls.Add(r); а сперва создать массив и вкрячить его в конце через pbMain.Controls.AddRange(...)

И delegate(object o, EventArgs e) {
...
};

Опишите отдельно... просто громоздко... как-то...
...
Рейтинг: 0 / 0
Как ускорить работу кода?
    #38691027
petalvik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SNenko,

O_O
Жуть! 400 запросов к БД!
На каждой итерации таймер создаётся и запускается...


Частично можно оптимизировать, если создать все используемые контролы один раз, например, при запуске программы. То есть сделать их полями, а не локальными переменными.

Должен быть всего один запрос к БД.

Возможно, чуть помогут вызовы методов SuspendLayout() и ResumeLayout() в начале и конце соответственно.
...
Рейтинг: 0 / 0
Как ускорить работу кода?
    #38691030
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SNenko,

20x20 из UserControl-компонентов - выбросить нахер компоненты

тексты и фон рисовать поверх картинки , клики мыши отрабатывать на картинке.
...
Рейтинг: 0 / 0
Как ускорить работу кода?
    #38691031
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petalvikЖуть! 400 запросов к БД!
На каждой итерации таймер создаётся и запускается...


не на итерации, а по клику
...
Рейтинг: 0 / 0
Как ускорить работу кода?
    #38691033
petalvik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А, таймер по клику запускается. Сразу не разглядел.
...
Рейтинг: 0 / 0
Как ускорить работу кода?
    #38691113
bazile
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SNenko, поставь вместо pbMain.Visible = false; вызов pbMain.SuspendLayout();
А вместо pbMain.Visible = true; соответственнно вызов pbMain.ResumeLayout();

Также следует избавиться от анонимной функции и заменить её на обычную функцию. В коде используется захват локальной переменной r. Чтобы код откомпилировался нужно добавить в начале функции следующую строку:
Код: c#
1.
Cell r = (Cell)(((Control)o).Parent);


Здесь предполагается что Cell является родителем для кнопки. Если есть еще один или несколько уровней вложенности, то не составит труда написать extension функцию FindParent<T> для класса Control которая найдет родителя нужного типа.
...
Рейтинг: 0 / 0
Как ускорить работу кода?
    #38691310
Фотография Василий Викторович
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SNenko,

1) разделение логики и интерфейса, вспоминаем парадигму MVC, т. е. посреди настройки внешнего вида не должен быть код работающий с данными
2) вынести sql в отдельную процедуру на ms sql сервер -> оптимизация sql кода, пайджинг на стороне ms sql server'a и все такое
3) 2 сторонний databinding на основе механизмов NET

После этого можно подумать дальше
...
Рейтинг: 0 / 0
Как ускорить работу кода?
    #38691333
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Василий ВикторовичSNenko,

1) разделение логики и интерфейса, вспоминаем парадигму MVC, т. е. посреди настройки внешнего вида не должен быть код работающий с данными
2) вынести sql в отдельную процедуру на ms sql сервер -> оптимизация sql кода, пайджинг на стороне ms sql server'a и все такое
3) 2 сторонний databinding на основе механизмов NET

После этого можно подумать дальше
Все бы ничего, только к коду топикстартера это имеет мало отношения
...
Рейтинг: 0 / 0
Как ускорить работу кода?
    #38691349
Фотография Василий Викторович
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Изопропил,

Вот мне интересно откуда вы взяли что эти рекомендации не помогут? как минимум я тут вижу код требующий рефакторинга, правда истинное название этого немного другое ну да ладно,
1) MVC - причины: котлеты отдельно мухи отдельно, т. е. разнести как минимум настройку интерфейса и обращение к БД в 2 разные функции, именно функции а не реализованный в середине функции анонимный делегат
2) Sql, голый sql запрос выдает с головой уровень писавшего это, как минимум обвернуть это в хранимую процедуру и ее дергать о технологиях ОRM и иже с ними я промолчу, о пайдженге на стороне сервера чтобы не тянуть тысячи записей тоже
3) ручное создание ячеек как минимум дурно пахнет так как уже давным - давно применяют DataBindings колекций обьектов к элементам интерфейса причем биндинг является двух сторонним со всякими интересными плюшками в виде генераций подтаблиц и валидаторов пользовательского ввода

P. S. код - результат человека только начавшего делать первые шаги в освоении языка и по этому допускающего определенные детские промахи, это исправимо, года через 1,5 после того как наберется опыта
...
Рейтинг: 0 / 0
Как ускорить работу кода?
    #38691373
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Василий ВикторовичВот мне интересно откуда вы взяли что эти рекомендации не помогут?
Вы, не читая кода, дали абстрактные советы

1) анонимный делегат вызывается только при клике мышью - на быстродействие никак не влияет
2) SQL запрос - простое добавление записи, запрос с параметрами - всё в порядке.
какой тут пейджинг и ORM? (что характерно - тоже по клику вызывается)
3)проблема здесь не в в отсутствии байндинга, а в создании сотен контролов

достаточно рисовать текст непосредственно поверх картинки и клики отрабатывать на картинке
...
Рейтинг: 0 / 0
Как ускорить работу кода?
    #38691488
SNenko
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Говоря о мухах и котлаетах, вы безусловно правы.

Почищу код и выложу результат
...
Рейтинг: 0 / 0
Как ускорить работу кода?
    #38692055
SNenko
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Быстрее работать не стало, но уменьшилось количество неточностей.

Щас закину в масив. Использу pbMain.Controls.AddRange(...).
Но это для порядка.
Не думаю что поможет..
Буду делать обработку кликов на картинке pbMain.
Спасибо за советы.

Выложу потом следюущий код.

это процедура:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
public static void CreateSections(PictureBox pbMain, IDictionary<string, string> dic, int cellCountRows = 20, int cellCountColumns =20 )
{
	pbMain.SuspendLayout();
	
	MyImage image = new MyImage(pbMain);
	MyCell cell = new MyCell(image, cellCountRows, cellCountColumns);
	MyCurrentCellPosition curr = new MyCurrentCellPosition(image, cell);
	
	for (int y = 1; y <= cellCountRows; y++)
	{
		for (int x = 1; x <= cellCountColumns; x++)
		{
			Cell r = new Cell(x*y, curr.y, curr.x, cell.size, dic["id"], ConnStr);
			pbMain.Controls.Add(r);
			curr.NewCell();
		}
		curr.NewRow();
	}
	pbMain.ResumeLayout();
}


А это класы к ней:

Код: 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.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
        class MyImage
        {
            public int Left;
            public int Top;
            public int Right;
            public int Bottom;
            public Size size;

            public MyImage(PictureBox pbMain)
            {
                this.size = getZoomedImage(pbMain);
                this.Left = (pbMain.ClientSize.Width - size.Width) / 2;
                this.Top = (pbMain.ClientSize.Height - size.Height) / 2;
                generate_RightBottom();
                rounding();
            }
            
            private void generate_RightBottom()
            {
                this.Right = this.Left + this.size.Width;
                this.Bottom = this.Top + this.size.Height;
            }
            private void rounding()
            {
                size.Width = takeTenPercent(size.Width);
                size.Height = takeTenPercent(size.Height);
            }
            private int takeTenPercent(int value)
            {
                if (value % 10 > 0)
                    return Convert.ToInt32(Math.Round((double)value / 10) * 10);
                return value;
            }
            //get size of image after zoom in picturebox
            private static Size getZoomedImage(PictureBox pictureBox1)
            {
                float x = pictureBox1.ClientSize.Width; // Ширина клиентской области
                float y = pictureBox1.ClientSize.Height; // Высота клиентской области

                float z1 = pictureBox1.Image.Width; //Ширина загруженного изображения
                float z2 = pictureBox1.Image.Height; //Высота загруженного изображения

                float q;  // Коэффициент
                float q1; //Отмасштабированная ширина
                float q2; //Отмасштабированная высота

                if (z1 > x | z2 > y)
                {
                    if (z1 > z2)  // z1>x
                    {
                        q = z1 / x;//коофіцієнт = восота зобр/ висота блоку

                        q1 = z1 / q;
                        q2 = z2 / q;
                        if (q2 > y)
                        {
                            q = z2 / y;
                            q1 = z1 / q;
                            q2 = z2 / q;
                            return new Size((int)q1, (int)q2);
                        }
                        else
                        {
                            return new Size((int)q1, (int)q2);
                        }
                    }
                    if (z2 > z1)  // z2>y
                    {
                        q = z2 / y;
                        q1 = z1 / q;
                        q2 = z2 / q;
                        if (q1 > x)
                        {
                            q = z1 / x;
                            q1 = z1 / q;
                            q2 = z2 / q;
                            return new Size((int)q1, (int)q2);
                        }
                        else
                        {
                            return new Size((int)q1, (int)q2);
                        }
                    }
                }
                return new Size((int)z1, (int)z2);
            }

        }

        class MyCell
        {
            public Size size;

            public MyCell(MyImage image, int cellCountRows, int cellCountColumns)
            {
                this.size = new Size(Convert.ToInt32(image.size.Width / cellCountColumns), Convert.ToInt32(image.size.Height / cellCountRows));
            }
        }

        class MyCurrentCellPosition
        {
            MyImage image;
            public int x;
            public int y;

            public MyCell cell;

            public MyCurrentCellPosition(MyImage image, MyCell cell)
            {
                this.x = image.Left;
                this.y = image.Top;
                this.image = image;
                this.cell = cell;
            }

            public void NewRow()
            {
                this.y += cell.size.Height;
                this.x = image.Left;
            }

            public void NewCell()
            {
                this.x += cell.size.Width;
            }
        }


...
Рейтинг: 0 / 0
Как ускорить работу кода?
    #38692119
SNenko
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Нащет скорости обработки ошибся.
Если использовать pbMain.Controls.AddRange(cells), обработка ускоряется раза в полтора.


предыдущий вариант(с класами): 2756 микросекунд
используя AddRange : 1110 микросекунд

но это всеравно много..

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
public static void CreateSections(PictureBox pbMain, IDictionary<string, string> dic, int cellCountRows = 20, int cellCountColumns =20 )
{
	MyImage image = new MyImage(pbMain);
	MyCell cell = new MyCell(image, cellCountRows, cellCountColumns);
	MyCurrentCellPosition curr = new MyCurrentCellPosition(image, cell);
	
	Cell[] cells = new Cell[401];
	for (int y = 1; y <= cellCountRows; y++)
	{
		for (int x = 1; x <= cellCountColumns; x++)
		{
			int number = x * y;
			cells[number] = new Cell(number, curr.y, curr.x, cell.size, dic["id"], ConnStr);
			curr.NewCell();
		}
		curr.NewRow();
	}
	pbMain.SuspendLayout();
	pbMain.Controls.AddRange(cells);
	pbMain.ResumeLayout();
}




Дело в том, что во время AddRange(как и в предыдущей поэлементной загрузке), изображение загружается кубиками.
Это при условиях:
pbMain.Visible=false;
pbMain.SuspendLayout();
...
Рейтинг: 0 / 0
Как ускорить работу кода?
    #38692210
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SNenko,

контролы то зачем нужны? клик ловить и текстовое сообщение показывать?
...
Рейтинг: 0 / 0
Как ускорить работу кода?
    #38692764
SNenko
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Изопропил,
Так до меня было. Поэтому, я изменяю по-этапно.
Думаю, lblText, вообще можно убрать, заменив простой переменной.

Это конструкто класа Cell:
Код: 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.
        public Cell(int number, int Top, int Left, Size size, string dic_id, string ConnStr)
        {
            InitializeComponent();
            this.Name = "VisComponent" + number.ToString();
            this.Top = Top;
            this.Left = Left;
            this.lblText.Text = number.ToString();
            this.Size = size;

            this.lblText.Size = this.Size;
            this.pnMain.Size = this.Size;

            
            this.pnMain.Click += delegate(object o, EventArgs e)
            {

                using (SqlConnection con = new SqlConnection(ConnStr))
                {
                    this.lblText.Visible = true;
                    this.lblText.ForeColor = Color.Red;
                    this.lblText.BackColor = Color.Red;

                    con.Open();
                    string sql = " insert into tbl_Transaction(AssmID, Position, LastUpdate) " +
                                    " values(@AssmID, @Position, GETDATE()) ";
                    using (SqlCommand com = new SqlCommand(sql, con))
                    {
                        com.Parameters.Add("@AssmID", dic_id);
                        com.Parameters.Add("@Position", this.lblText.Text);
                        com.ExecuteNonQuery();
                    }
                }

                System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();
                timer.Interval = 1000;
                timer.Tick += (source, u) => { this.lblText.Visible = false; timer.Stop(); };
                timer.Start();
            };
        }

...
Рейтинг: 0 / 0
Как ускорить работу кода?
    #38692797
SNenko
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
К стати, выяснилось, что в два раза быстрее оно работает, потомучто размещает в два раза меньше компонентов.
Даже незнаю куда они с масива деваются.(картинка выше)
...
Рейтинг: 0 / 0
Как ускорить работу кода?
    #38692807
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SNenko,

я правильно понимаю, что по клику нужно сделать запись в базу на секунду нарисовать красный прямоугольник?
...
Рейтинг: 0 / 0
Как ускорить работу кода?
    #38692824
SNenko
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ИзопропилSNenko,

я правильно понимаю, что по клику нужно сделать запись в базу на секунду нарисовать красный прямоугольник?
Именно так.
...
Рейтинг: 0 / 0
Как ускорить работу кода?
    #38692827
SNenko
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
SNenkoК стати, выяснилось, что в два раза быстрее оно работает, потомучто размещает в два раза меньше компонентов.
Даже незнаю куда они с масива деваются.(картинка выше)
Тут моя ошибка я умножал: х*у.
надо было просто number++;
...
Рейтинг: 0 / 0
Как ускорить работу кода?
    #38692838
SNenko
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Получается, что поэлементно и массивом оно заносит почти одинаково(разница на 100 микросекунд).
Я думаю, что много времени занимает поэлементная прорисовка.
Незнаю как ее отключить..
Во всяком случае, код стал более читабелен(для меня)

Приступлю к варианту с кликами на bictureBox. Тоесть, без масива, а с прорисовкой конкретного килика.
...
Рейтинг: 0 / 0
Как ускорить работу кода?
    #38692932
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SNenkoПриступлю к варианту с кликами на bictureBox. Тоесть, без масива, а с прорисовкой конкретного килика.
правильный путь.

потребуется одна панель, на ней рисуется картинка и закрашиваются прямоугольники
и никаких лишних контролов
...
Рейтинг: 0 / 0
Как ускорить работу кода?
    #38693245
Roman Mejtes
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Изопропил,

Перфоманс Аналайзер вам в помощь, на нём увидите где программа больше всего тормозит и там уже будите думать, как это решить.
...
Рейтинг: 0 / 0
Как ускорить работу кода?
    #38693459
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Roman MejtesИзопропил,

Перфоманс Аналайзер вам в помощь, на нём увидите где программа больше всего тормозит и там уже будите думать, как это решить.


Господа теоретики, не нужна мне помощь, я читать код умею.
Да и задачка не у меня.

В данном случае - тормоза на беспощадном и бессмысленном создании сотен windows контролов.
Несчастный обработчик клика мыши - не нуждается в оптимизации. Если только с эстетической точки зрения
...
Рейтинг: 0 / 0
Как ускорить работу кода?
    #38693510
SNenko
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Roman MejtesИзопропил,

Перфоманс Аналайзер вам в помощь, на нём увидите где программа больше всего тормозит и там уже будите думать, как это решить.
я пользуюсь своим класом.
Но спасибо Вам за совет!

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
public class SW : Stopwatch
{
	public SW()
	{
		this.Start();
	}

	public void write(string text)
	{
		if (this.IsRunning)
		{
			this.Stop();
			Console.WriteLine("{0} (час: {1})", text, this.ElapsedMilliseconds);
			//--Console.WriteLine("{0} (час: {1})", text, this.Elapsed);
			this.Reset();
		}
		else
			Console.WriteLine("{0}", text);
		this.Start();
	}
}
...
Рейтинг: 0 / 0
25 сообщений из 27, страница 1 из 2
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Как ускорить работу кода?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]