改善行数据

时间:2013-11-10 03:00:37

标签: c# algorithm

我在Excel电子表格上有N行(可能不低于1000行)。在这张表中,我们的项目有150列,如下所示:

enter image description here

现在,我们的应用程序需要从GUI工作表上的Excel文件表中复制数据(使用普通Ctrl+C)并粘贴(使用Ctrl+V)。我通过使用Divide and Conquer或其他一些机制增加了。目前我还不确定如何解决这个问题。以下是我的代码的部分内容:

以上代码按行调用:

请知道我的问题需要比代码优化更多的算法解决方案,但是包含代码相关优化的任何答案也将受到赞赏。 (标记为Linq,因为虽然没有看到我在代码的某些部分使用了linq。)

7 个答案:

答案 0 :(得分:6)

1。 IIRC dRow["Condition"]dRow[index]慢得多,因为每次都必须进行查找。在调用之前找出列所具有的索引。

public virtual void ValidateAndFormatOnCopyPaste(DataTable DtCopied, int CurRow, int conditionIndex, int valueIndex)
{
    foreach (DataRow dRow in dtValidateAndFormatConditions.Rows)
    {
         string Condition = dRow[conditionIndex];
         string FormatValue = Value = dRow[valueIndex];
         GetValidatedFormattedData(DtCopied,ref Condition, ref FormatValue ,iRowIndex);
         Condition = Parse(Condition);
         dRow[conditionIndex] = Condition;
         FormatValue = Parse(FormatValue );
         dRow[valueIndex] = FormatValue;
    }
}

2. 如果您要实时更新Excel文档,则还应在此过程中锁定工作表更新,以便在每次更改单元格时不重新绘制文档。

3。 virtual方法也会导致性能下降。

答案 1 :(得分:2)

这样一个问题的一般答案是你想尽可能多地从行循环中移出较重的处理,所以它只需要执行一次而不是每一行。

如果不确切知道验证/格式化系统的工作原理,很难提供更多细节,但我可以提供一些“指针”:

  • 是否可以从您的条件表中构建某种缓存数据结构?这将消除内循环中所有繁重的DataTable操作
  • 我能想到的最有效的批量验证/格式化解决方案是根据您的条件构建一个C#脚本,将其编译成一个委托,然后只评估每一行。我不知道你的问题是否可行......

答案 2 :(得分:1)

该算法有两项改进建议: -

a.U如果可能的话可以使用多线程来加速恒定因子(需要)     测试以获得实际值)。你可以使用多线程来评估行中的行     平行。

湾如果即使一列无效也可以停止处理行,那么你可以停止      处理那一行。此外,您可以分析大量数据的输入数据      安排列减少可能性无效,然后检查      此计算顺序中的列。你还可以安排谓词      用于检查验证的列的验证条件

可能提高性能的建议算法: -

for i in totalconds :
   probability(i) = 0

for record in largeDataSet : 
    for col in record : 
        for cond in conditions :
            if invalid(cond,col) : 
               probability(cond)++

sort(probability(cond),condorder,order=decreasing)

按照condorder的顺序检查条件

这是学习算法,可用于计算谓词评估的顺序,以便对条件进行有效的短路评估,但对有效输入需要相同的时间。您可以在大型样本输入数据集上离线评估此订单,并在实时使用期间将其存储在数组中。

编辑:我错过的另一项改进是对具有小范围有效值的列使用哈希表,因此我们只是检查它是否在哈希表。同样,如果无效值范围很小,那么我们在哈希表中检查它们。可以在评估开始之前使用文件填充哈希表。

答案 3 :(得分:0)

'string Condition = dRow [“Condition”]'之类的操作相当繁重,因此我建议在GetValidatedFormattedData的调用周围立即将行枚举(for-cycle)从ValidateAndFormat方法移动到ValidateAndFormatOnCopyPaste方法。 / p>

答案 4 :(得分:0)

预备步骤:

  • 创建一个接受1 dataRow并处理它的任务类
  • 创建任务队列
  • 使用Y worker创建一个线程池

算法

  1. 当您获得N行时,将所有这些行添加为任务队列
  2. 让工作人员从任务队列中开始执行任务
  3. 当任务响应返回时,更新数据表(可能最初是克隆)
  4. 完成所有任务后返回新数据表
  5. 可能的改进

    • 正如维克拉姆所说,你可能会短路你的情况,如果价值10,你知道它已经是一个错误,不要费心去检查140个条件的其余部分,但这只是在符合你要求的情况下,如果你的要求要求所有150的检查条件,然后你无法逃脱那个
    • 更改任务类以获取行数据列表而不是1,这可能会因线程之间的上下文切换而改善,如果它们很快完成的话

    我还没有想过的其他想法

    • 首先对数据进行排序,可能存在短路某些已知条件的速度优势
    • 校验和整行,将其存储到带有结果的数据库中,实质上缓存参数/结果,以便下次运行具有完全相同值/字段的内容时,可以从缓存中提取
    • 整行的其他校验和购买是改变,让我们说你有某种键并且你正在寻找更改的数据,除了键之外的所有内容的校验和将告诉你是否某些值发生了变化以及它是否均匀值得看看所有其他专栏的条件

答案 5 :(得分:0)

您可以使用数据表。 试试这个 datatable.Select(string.Format(" [Col1] =' {0}'",id))。ToList()。ForEach(r => r [&# 34; Col1"] =数据); 看到链接 https://msinternal1.engageexpress.com/sf/MTY1NDNfMTY4NTM4

答案 6 :(得分:0)

我知道这是一种蛮力,但你可以把它与别人的建议结合起来:

Parallel.ForEach(dtValidateAndFormatConditions.Rows, dRow =>
        {
             string Condition = dRow[conditionIndex];
             string FormatValue = Value = dRow[valueIndex];
             GetValidatedFormattedData(DtCopied,ref Condition, ref FormatValue ,iRowIndex);
             Condition = Parse(Condition);
             FormatValue = Parse(FormatValue);
             lock (dRow)
             {
                 dRow[conditionIndex] = Condition;
                 dRow[valueIndex] = FormatValue;
             }
        });