0

我有一份人力清单(40 人)。我需要为每个人循环一年(365 天)来提取每天的数据。但这需要太多时间。有什么建议可以提高速度或其他方法吗?

for (int man=0;man<40;man++)
{
    for (DateTime date = DateTime.Now.Date;date<DateTime.Now.AddYears(1);date=date.AddDays(1))
    {
        //do stuff
    }

}

编辑:东西涉及从数据库中提取数据,我得到每个人参与的项目,以及每个人项目的开始和结束日期。(每个人都有自己的桌子,并且有一张主桌,上面有所有男人的名单)。我有一个 datagridview,其中我在垂直轴上显示 40 个人。横向365天。取决于编号。在每个人都参与的项目中,我需要对相应的单元格进行颜色编码。

编辑2://A是一个连接到数据库的类,转发查询并返回结果

 void colourchanger()
    {
        for (int m = 0; m < i; m++)//i=40
        {
            int copy = m;                             
            List<string>[] list = new List<string>[5];
            int number = A.Countproj(abc);//return no. of projects under man
            list = A.manprojselect(abc);//returns project details
            thread[copy] = new Thread(() => threader(copy,2*copy,list,number));
            thread[copy].Start();
        }
    }

void threader(int p, int x,List<string>[] list,int numberer)
    {
        DateTime labeldate;
        DataGridViewCellStyle AL = new DataGridViewCellStyle();
        AL.BackColor = Color.Brown;//AL
        DataGridViewCellStyle NS = new DataGridViewCellStyle();
        NS.BackColor = Color.Aqua;//NS 
        DataGridViewCellStyle training = new DataGridViewCellStyle();
        training.BackColor = Color.Maroon;//training
        DataGridViewCellStyle one = new DataGridViewCellStyle();
        one.BackColor = Color.Green;//one project
        DataGridViewCellStyle overseas = new DataGridViewCellStyle();
        overseas.BackColor = Color.Blue;//overseas
        DataGridViewCellStyle two = new DataGridViewCellStyle();
        two.BackColor = Color.Yellow;//2 projects
        DataGridViewCellStyle three = new DataGridViewCellStyle();
        three.BackColor = Color.Red;//3 projects
        DataGridViewCellStyle unfeasible = new DataGridViewCellStyle();
        unfeasible.BackColor = Color.Black;//self explanatory
        DataGridViewCellStyle none = new DataGridViewCellStyle();
        none.BackColor = Color.Gray;//self explanatory


        string[] projname;
        string[] country;   
        string[] start; 
        string[] end;   
        string temp;    
        DateTime startdate;
        DateTime enddate;
            int[] track = new int[366];
            string[] projnames = new string[366];

                for (int y = 0; y < 366; y++)
                {
                    projname = list[0].ToArray();
                    country = list[2].ToArray();
                    start = list[3].ToArray();
                    end = list[4].ToArray();
                    temp = dataGridView1.Rows[x].Cells[y].ToolTipText;
                    temp = temp[0].ToString() + temp[1].ToString() + temp[2].ToString() + temp[3].ToString() + temp[4].ToString() + temp[5].ToString() + temp[6].ToString() + temp[7].ToString() + temp[8].ToString() + temp[9].ToString();
                    labeldate = DateTime.ParseExact(temp,
                                           "dd-MM-yyyy",
                                           CultureInfo.InvariantCulture);
                    for (int l = 0; l < numberer; l++)
                    {
                        startdate = DateTime.ParseExact(start[l],
                                           "dd-MM-yyyy HH:mm:ss",
                                           CultureInfo.InvariantCulture);

                        enddate = DateTime.ParseExact(end[l],
                                           "dd-MM-yyyy HH:mm:ss",
                                           CultureInfo.InvariantCulture);

                        int r1 = DateTime.Compare(startdate, labeldate);
                        int r2 = DateTime.Compare(labeldate, enddate);
                        if (r1 <= 0 && r2 <= 0)
                        {
                            track[y]++;
                            projnames[y] = projnames[y] + ", " + projname[l];
                            if (String.Compare(country[l], "Singapore ") != 0)
                            {
                                track[y] = 10;
                                projnames[y] = " " + projname[l];
                            }

                            if (String.Compare(projname[l], "ANNUAL LEAVE") == 0)
                            {
                                track[y] = 20;
                                projnames[y] = " " + projname[l];
                            }

                            if (String.Compare(projname[l], "NATIONAL SERVICE") == 0)
                            {
                                track[y] = 30;
                                projnames[y] = " " + projname[l];
                            }

                            if (String.Compare(projname[l], "TRAINING") == 0)
                            {
                                track[y] = 40;
                                projnames[y] = " " + projname[l];
                            }


                        }


                    }
                }

                for (int y = 0; y < 366; y++)
                {
                    if (track[y] == 0)
                    {
                        dataGridView1.Rows[x].Cells[y].Style = none;
                        dataGridView1.Rows[x].Cells[y].ToolTipText = dataGridView1.Rows[x].Cells[y].ToolTipText + projnames[y];
                    }
                    if (track[y] == 1)
                    {
                        dataGridView1.Rows[x].Cells[y].Style = one;
                        dataGridView1.Rows[x].Cells[y].ToolTipText = dataGridView1.Rows[x].Cells[y].ToolTipText + projnames[y];
                    }
                    if (track[y] == 2)
                    {
                        dataGridView1.Rows[x].Cells[y].Style = two;
                        dataGridView1.Rows[x].Cells[y].ToolTipText = dataGridView1.Rows[x].Cells[y].ToolTipText + projnames[y];
                    }
                    if (track[y] == 3)
                    {
                        dataGridView1.Rows[x].Cells[y].Style = three;
                        dataGridView1.Rows[x].Cells[y].ToolTipText = dataGridView1.Rows[x].Cells[y].ToolTipText + projnames[y];
                    }
                    if (track[y] == 10)
                    {
                        dataGridView1.Rows[x].Cells[y].Style = overseas;
                        dataGridView1.Rows[x].Cells[y].ToolTipText = dataGridView1.Rows[x].Cells[y].ToolTipText + projnames[y];
                    }
                    if (track[y] == 20)
                    {
                        dataGridView1.Rows[x].Cells[y].Style = AL;
                        dataGridView1.Rows[x].Cells[y].ToolTipText = dataGridView1.Rows[x].Cells[y].ToolTipText + projnames[y];
                    }
                    if (track[y] == 30)
                    {
                        dataGridView1.Rows[x].Cells[y].Style = NS;
                        dataGridView1.Rows[x].Cells[y].ToolTipText = dataGridView1.Rows[x].Cells[y].ToolTipText + projnames[y];
                    }
                    if (track[y] == 40)
                    {
                        dataGridView1.Rows[x].Cells[y].Style = training;
                        dataGridView1.Rows[x].Cells[y].ToolTipText = dataGridView1.Rows[x].Cells[y].ToolTipText + projnames[y];
                    }
                    if (track[y] > 3 && (track[y] != 10 && track[y] != 20 && track[y] != 30 && track[y] != 40))
                    {
                        dataGridView1.Rows[x].Cells[y].Style = unfeasible;
                        dataGridView1.Rows[x].Cells[y].ToolTipText = dataGridView1.Rows[x].Cells[y].ToolTipText + projnames[y];
                    }
                }
    }

使用的数据库:SQL CE

编辑 3: Manprojselect() 已发布

public List<string>[] manprojselect(string manpowername)
        {
            string query = "SELECT * FROM "+ manpowername;

            //Create a list to store the result
            List<string>[] list = new List<string>[5];

            list[0] = new List<string>();
            list[1] = new List<string>();
            list[2] = new List<string>();
            list[3] = new List<string>();
            list[4] = new List<string>();
            //Open connection
            if (this.OpenConnection() == true)
            {
                //Create Command
                SqlCeCommand cmd = new SqlCeCommand(query, connection);
                //Create a data reader and Execute the command
                SqlCeDataReader dataReader = cmd.ExecuteReader();

                //Read the data and store them in the list
                while (dataReader.Read())
                {
                    list[0].Add(dataReader["Name"] + "");
                    list[1].Add((dataReader["Allotment_number"]).ToString() + "");
                    list[2].Add(dataReader["Country"] + "");
                    list[3].Add(dataReader["Start_date"] + "");
                    list[4].Add(dataReader["End_date"] + "");

                }
                //close Data Reader
                dataReader.Close();
                //close Connection
                this.CloseConnection();
                //return list to be displayed
                return list;
            }
            else
            {
                return list;
            }

        }
4

5 回答 5

4

它只循环了 365*40 次,而且是一个简单的检查。除此之外,您的所有减速都是由//do stuff.

我要补充一点,这实际上是一个常见问题 -//do stuff然后将花费的时间乘以 365*40(假设东西在人和天上花费的时间是一致的)。

于 2013-05-16T22:14:25.770 回答
3

尝试从数据库中提取数据作为单个批量查询或每个人至少单个查询。

在代码中分析您的数据,即使使用未优化的代码,它也会比查询每个单元格更快。

于 2013-05-16T22:26:21.773 回答
2

如前所述,//do stuff是罪魁祸首。

如果没有更多信息,我只能建议您尝试使用该Parallel.For方法并使用更多线程(如果您有多个可用的逻辑 CPU 内核,则很有用)。

请记住,这需要您lock考虑,因为对共享变量的并发访问可能会导致问题。

于 2013-05-16T22:17:21.593 回答
1

纯娱乐。我怎样才能优化那个循环?我试过这个

void Main()
{
    Stopwatch sw = new Stopwatch();
    sw.Start();
    int max = DateTime.Today.AddYears(1).Subtract(DateTime.Today).Days;
    for (int man=0;man<40;man++)
    {
        for (int x = 0; x <= max; x++)
        {
            //do stuff
        }
    }
    sw.Stop();
    Console.WriteLine(sw.Elapsed.TotalMilliseconds);
    sw.Reset();
    sw.Start();
    for (int man=0;man<40;man++)
    {
        for (DateTime date = DateTime.Now.Date;date<DateTime.Now.AddYears(1);date=date.AddDays(1))
        {
            //do stuff
        }
    }
    sw.Stop();
    Console.WriteLine(sw.Elapsed.TotalMilliseconds);

}

第一个循环以一年中的天数为单位计算长度,然后使用整数循环,第二个循环是 OP。
第一个循环快了惊人的 19 毫秒。
好吧,足够有趣,回去工作并尝试优化那些东西

于 2013-05-16T22:28:05.903 回答
0

您的问题是您尝试对数据库进行 365*40 的单独查询。通常,您希望更多地在服务器端进行评估。

回答您的直接问题:是的,您可以使代码运行得更快。但是,这不会解决您的问题。

您可以将当前日期存储到一个局部变量中,然后使用它来代替对 DateTime.Now 的所有调用,后者每次都会检查系统时间。

var now=DateTime.Now;
var yearFromNow = DateTime.Now.AddYears(1);

...然后在循环中使用这些新变量。

您还可以将所有日期存储在列表中,从而减少循环内所需的计算次数:

var dates = Enumerable.Range(0,365).Select(n=>now.AddDays(n)).ToList();

然后您可以在循环中访问此列表:

for (int man=0;man<40;man++)
{
    foreach (var dt in dates)
    {
        //do stuff
    }
}

...但这不是您的主要性能问题所在。相反,您应该在此处发布//do stuff 正文,以及您正在使用的数据库访问类型(LINQ2Sql、EF 等),以便我们可以查看是否可以优化整个事情以获得显着收益。

不应为每个循环通过重新打开连接。

于 2013-05-16T22:32:38.410 回答