【问题标题】:How to get row by one column faster in C#?如何在 C# 中更快地逐行获取?
【发布时间】:2010-05-10 15:11:37
【问题描述】:

我有一个包含 30000 行的列 Value 和列 Name 的 DataTable。现在我想从 Value 指定的行中获得非常快的 Name 。如何快速做到这一点?我对这个表有 40000 个不同值的请求。

我对 C# 中的解决方案感兴趣,在数据库方面。

【问题讨论】:

    标签: c# optimization datatable


    【解决方案1】:

    假设你已经有了 DataTable,你可以这样做:

    DataRows row = MyDataTable.Select("Value = 7")[0];
    string name = (string)row["name"];
    

    当然,如果您只是为了这个目的而检索 DataTable,最好只从数据库中选择您需要的数据。如果这是您保存在内存中的数据,那么我建议您使用 JMarsch 的使用字典的建议。

    【讨论】:

      【解决方案2】:

      数据表中的数据是从哪里来的?在数据库端进行过滤总是比将整个数据库表检索到数据表中然后在那里过滤要快得多。在数据库中速度要快几个数量级。

      【讨论】:

      • 它可以来自 XML、数据库或解析的纯文本。所以很遗憾,我不能对数据库进行这种优化。
      【解决方案3】:

      您可以使用 DataView,并将排序顺序设置为键。这将导致构建内存索引。

      然而如果这只是一个只有键和值的简单数据表,我建议您改用 Dictionary 或 HashTable。使用 Dictionary 您将获得更好的性能(在测试中,我们已将数百万个项目加载到字典中,并获得亚秒级查找 - 查找的性能是 O(1) 或 O(logn),我可以'不记得是哪一个了——不管怎样,都快疯了。

      【讨论】:

      • O(1) 用于字典。排序字典的 O(logn)
      【解决方案4】:

      不要使用 DataTable - 使用请求访问数据库。严重地。您需要具有索引的东西,并针对处理它认为的少量数据进行了优化。

      【讨论】:

      • 我的数据来自XML、数据库或纯文本,所以很遗憾我无法将此任务传递给数据库。
      • 从 XML 加载到优化的类。节省大量内存 - 在这种情况下,内存 = 性能。当一个类变得“脏”时,把它放到一个类列表中写出来。
      【解决方案5】:

      您有两种选择来进行客户端搜索:

      1. 使用DataView

        DataView view = new DataView(table);
        view.Sort = "Value asc";
        int index = view.Find(value);
        // you now have the index of the row in question, or -1 if it was not found
        
      2. 使用Dictionary。这会更快一些,但需要更多的前期工作和维护。假设Value是一个整数列,Name是一个字符串,

        Dictionary<int, string> lookup = table.Rows.ToDictionary(
            r => (int)r["Value"], 
            r => (string)r["Name"]);
        string name = lookup[value];
        

        或者,如果可能存在不存在的值,

        string name;
        if(lookup.TryGetValue(value, out name)) ...
        

      虽然Dictionary 可能会更快,但这两个选项都将相当快。它唯一的缺点是您必须在更改发生时使其与表保持同步(假设更改可以发生)。

      显然,数据库本身执行此过滤更容易,但我将决定是否应在客户端执行此操作。

      【讨论】:

        【解决方案6】:

        在 .Net 中,DataTables 是昂贵的结构。一个更简单、更有效的结构是字典。你可以这样定义:

            System.Collections.Generic.Dictionary<string, string> nameValueList = new Dictionary<string, string>();
        

        然后你可以像这样加载它:

        nameValueList.Add("name1", "value1");
        

        ...假设名称是唯一的,否则您将收到“ArgumentException”。
        最后,您可以调用如下值:

        string res = nameValueList["name1"];
        

        如果预期事务的数量足以证明转换数据的初始开销是合理的,我认为这是最快的实现之一。

        【讨论】:

          猜你喜欢
          • 2014-03-11
          • 1970-01-01
          • 1970-01-01
          • 2011-06-18
          • 1970-01-01
          • 2011-07-07
          • 1970-01-01
          • 1970-01-01
          • 2016-03-01
          相关资源
          最近更新 更多