建议更好的逻辑

时间:2014-05-30 03:45:04

标签: c# logic

目前,我正在为一个早已离开的人(我的意思是离开公司)编写的旧项目代码进行性能改进。 我想改进的代码是:

DataTable dtSource = new DataTable();
DataTable dtSourceTemp = new DataTable();
dtSource = GetData();
dtSourceTemp = dtSource.Copy();

foreach (DataRow item in dtSource.Rows)
{
    if (Functions.parseString(item["COL_1"]).Equals("NG"))
    {
        foreach (DataRow itemTemp in dtSourceTemp.Rows)
        {
            if (Functions.parseString(itemTemp["PK_1"]).Equals(Functions.parseString(item["PK_1"]))
                && Functions.parseString(itemTemp["PK_2"]).Equals(Functions.parseString(item["PK_2"]))
                && Functions.parseString(itemTemp["PK_3"]).Equals(Functions.parseString(item["PK_3"])))
            {
                itemTemp["COL_1"] = "NG";
            }
        }
    }
}

逻辑是数据有4个主键(PK_1,PK_2,PK_3,PK_4)。 PK_1到3将定义项目系列,PK_4将是系列中的项目数。

如果系列中的任何项目是NG,则系列中的所有项目都是NG。

对于上面的代码,每次运行此代码时大约有80K条记录,将有更新的6.400.000.000循环(如果每个系列至少有1个NG项目)80.000行,这是非常低效的。

任何人都可以给我一个如何改进的建议吗?

请注意,所有这些工作都是为了向屏幕显示所需的数据(dtSourceTemp将是数据源),而不是实际更新数据库中的数据。

更新:

在思考之后,我认为这会更好:

DataTable dtSource = new DataTable();
DataRow[] drSource = dtSource.Select("COL_1 = 'NG'");

foreach(DataRow dr in drSource)
{
    string pk1 = dr["PK_1"].toString();
    string pk2 = dr["PK_2"].toString();
    string pk3 = dr["PK_3"].toString();

    //TO-DO:Code to update data in dtSource based on 3 PK
    //Something equal to SQL Script "Update tbl set COL_1 = 'NG' WHERE ...."
}

但是,我目前仍然在更新dtSource的数据,因为C#似乎没有任何可以做我想要的DataTable的功能。

1 个答案:

答案 0 :(得分:0)

由于您使用的是基本循环并且无法将其移动到数据库,因此优化程度不高。

话虽如此,你可以尝试调整某些事情,我会借此机会抛弃这可能会在https://codereview.stackexchange.com/中提出

1 - Functions.parseString

实际上会导致瓶颈的第一件事是Functions.parseString()正在做的事情。这应该是首先考虑并开始编写单元测试以确定基线并测量10,000次分析的速度与您认为会使其更快的任何变化。

2 - 更改If条件的顺序

根据实际存储的数据,您可以通过更改顺序来创建速度增加,以便更快地进行短路。

如果您的PK_#列类似于A,B,1 | A,B,2 | A,B,3等,那么最好先更改订单,以便在其他项目之前先检查PK_3,这样它就不会出现问题。在PK_3不匹配的情况下,大多数时间拨打parseString 4次。基本上,首先尝试按最独特的价值订购。

3 - 缓存某些值

为什么在每个项目总是相同时解析一些东西?

foreach (DataRow item in dtSource.Rows)
{
    if (Functions.parseString(item["COL_1"]).Equals("NG"))
    {
        var pk1 = Functions.parseString(item["PK_1"])
        var pk2 = Functions.parseString(item["PK_2"])
        var pk3 = Functions.parseString(item["PK_3"])

        foreach (DataRow itemTemp in dtSourceTemp.Rows)
        {
            if (Functions.parseString(itemTemp["PK_1"]).Equals(pk1)
                && Functions.parseString(itemTemp["PK_2"]).Equals(pk2)
                && Functions.parseString(itemTemp["PK_3"]).Equals(pk3))
            {
                itemTemp["COL_1"] = "NG";
            }
        }
    }
}

4 - 运行SQL查询而不是代码

(未经测试的MSSQL示例)

UPDATE YT
SET YT.COL_1 = 'NG'
FROM YOUR_TABLE YT
WHERE EXISTS (
    SELECT 1 
       FROM YOUR_TABLE YT2
       WHERE YT2.COL_1 = 'NG' 
         AND YT.PK_1 = YT2.PK_1 
         AND YT.PK_2 = YT2.PK_2 
         AND YT.PK_3 = YT2.PK_3
)

你真的没有其他的事情可做。你拥有的是超级基本的,并且大部分完全依赖于运行过程的处理器。