winforms C # .NET-루프 (for, foreach 등…)를 사용하는 동안 내 코드의 성능을 향상시키는 방법 [닫힌]
저는 대학 용 앱을 개발 중이며, 앱의 일부는 주간 수업 일정을 설정하는 것입니다.
내 매개 변수는 교실 번호, 요일 및 시간 슬롯입니다.
그래서 저는 다양한 교실을 가지고 있고 각 교실에는 숫자가 있습니다.
런타임에서 앱은 데이터베이스에있는 강의실 수에 따라 몇 개의 버튼을 생성하고 각 버튼에 강의실 번호를 설정합니다.
내가 원하는 것은 주어진 요일과 주어진 시간 슬롯에 특정 교실이 가득 찬 경우 각 교실 버튼에 "빨간색"BackColor를 표시하는 것입니다.
내가하고 싶은 일을 완수했고 내 코드는 오류없이 작동하지만 이제 유일한 문제는 성능입니다.
내 코드는 다음과 같습니다.
private OleDbConnection Connection = new OleDbConnection();
private void SomeMethod(string Day, string Time)
{
int MaxIndex = 0;
string str1 = "select Max([Row Index]) from Table";
OleDbCommand Command1 = new OleDbCommand(str1, Connection);
Connection.Open();
if (Command1.ExecuteScalar() == DBNull.Value)
MaxIndex = 1;
else
MaxIndex = Convert.ToInt32(Command1.ExecuteScalar());
Connection.Close();
for (int i = 0; i < MaxIndex; i++)
{
string str = "select [classroom Number] from Table where [Day] = @ParamDay and [Time] = @ParamTime and [Row Index] = @ParamIndex";
OleDbCommand Command = new OleDbCommand(str, Connection);
Command.Parameters.Add("@ParamDay", Day);
Command.Parameters.Add("@ParamTime", Time);
Command.Parameters.Add("@ParamIndex", i + 1);
Connection.Open();
OleDbDataReader reader = Command.ExecuteReader();
if (reader.Read())
{
foreach (Button btn in ButtonsPanel.Controls)
{
if (btn.Text == reader["classroom Number"].ToString())
{
btn.BackColor = Color.Red;
}
}
Connection.Close();
}
}
}
따라서이 코드는 내가 가질 것으로 예상되는 행이 200 개 있으면 약 13 초가 걸립니다.
질문은 ...이 13 초가 최소 2-4 초로 줄어들도록 코드에 할 수있는 일이 있습니까?
정보 : 인터넷에서 많이 검색했지만 여기에서 내 문제에 대한 해결책을 찾을 수 없습니다.
답변
for 사이클이 전혀 필요하지 않은 것 같습니다. 그리고 MaxIndex
둘 중 하나. 시간에 대한 기록을 다운로드하고 버튼을 표시하십시오.
private void SomeMethod(string Day, string Time)
{
HashSet<string> classNumbers = new HashSet<string>();
string str = "select [classroom Number] from Table where [Day] = @ParamDay and [Time] = @ParamTime";
using (OleDbCommand Command = new OleDbCommand(str, Connection))
{
Command.Parameters.Add("@ParamDay", Day);
Command.Parameters.Add("@ParamTime", Time);
Connection.Open();
using (OleDbDataReader reader = Command.ExecuteReader(CommandBehavior.CloseConnection))
{
while (reader.Read())
{
classNumbers.Add(reader["classroom Number"].ToString());
}
}
}
foreach (Button btn in ButtonsPanel.Controls)
{
if (classNumbers.Contains(btn.Text))
{
btn.BackColor = Color.Red;
}
}
}
개선하기 위해 변경할 수있는 두 가지 사항이 있습니다.
- 연결을 한 번만 열고 닫아 코드 실행 시간을 줄일 수 있습니다.
- 하나의 쿼리로 처리 할 모든 데이터를 가져옵니다.
아래 코드를 확인하십시오.
private OleDbConnection Connection = new OleDbConnection();
private void SomeMethod(string Day, string Time)
{
int MaxIndex = 0;
string str1 = "select Max([Row Index]) from Table";
OleDbCommand Command1 = new OleDbCommand(str1, Connection);
Connection.Open();
if (Command1.ExecuteScalar() == DBNull.Value)
MaxIndex = 1;
else
MaxIndex = Convert.ToInt32(Command1.ExecuteScalar());
string str = "select [classroom Number] from Table where [Day] = @ParamDay and [Time] = @ParamTime and [Row Index] between 1 and @ParamIndex";
OleDbCommand Command = new OleDbCommand(str, Connection);
Command.Parameters.Add("@ParamDay", Day);
Command.Parameters.Add("@ParamTime", Time);
Command.Parameters.Add("@ParamIndex", MaxIndex);
OleDbDataReader reader = Command.ExecuteReader();
while (reader.Read())
{
foreach (Button btn in ButtonsPanel.Controls)
{
if (btn.Text == reader["classroom Number"].ToString())
{
btn.BackColor = Color.Red;
}
}
}
Connection.Close();
}
내 의견에 따라 쿼리를 한 번만 실행하고 결과 집합을 반복하면됩니다. IO가 일반적으로 매우 느리기 때문에 이제 IO에 한 번만 액세스하므로 성능이 향상됩니다.
다음은 예입니다 (테스트되지 않음).
private void SomeMethod(string day, string time)
{
// Using statement helps to dispose any resources once done with the connection
// connectionString can be any string that opens your database
using (OleDbConnection connection = new OleDbConnection(connectionString))
{
// The query has removed the notion of index, it will just get all the data for that day and time
string query = "SELECT [classroom Number] FROM Table WHERE [Day] = @ParamDay AND [Time] = @ParamTime";
// Since OleDbCommand inherits from IDisposable, use a using statement
using (OleDbCommand command = new OleDbCommand(query, connection))
{
// Notice how we don't use index anymore
command.Parameters.Add("@ParamDay", day);
command.Parameters.Add("@ParamTime", time);
// Open connection here, don't need to close connection
connection.Open();
// Since OleDbDataReader inherits from IDisposable, use a using statement
using (OleDbDataReader reader = command.ExecuteReader())
{
// We're now looping through all the rows in the result set
while (reader.Read())
{
UpdateButtonColor(reader["classroom Number"].ToString());
}
}
}
}
}
private void UpdateButtonColor(string classroomNumber)
{
foreach (Button btn in ButtonsPanel.Controls)
{
if (btn.Text == classroomNumber)
{
btn.BackColor = Color.Red;
}
}
}
최신 버전의 C #에서는 using
명령문에 중괄호 (중첩 감소)가 필요하지 않습니다.
private void SomeMethod(string day, string time)
{
string query = "SELECT [classroom Number] FROM Table WHERE [Day] = @ParamDay AND [Time] = @ParamTime";
using OleDbConnection connection = new OleDbConnection(connectionString);
using OleDbCommand command = new OleDbCommand(query, connection);
command.Parameters.Add("@ParamDay", day);
command.Parameters.Add("@ParamTime", time);
connection.Open();
using OleDbDataReader reader = command.ExecuteReader();
while (reader.Read())
{
UpdateButtonColor(reader["classroom Number"].ToString());
}
}
이에 대한 문서는 여기 에서 찾을 수 있습니다 .