C# 字典 vs 二维数组
Posted
技术标签:
【中文标题】C# 字典 vs 二维数组【英文标题】:C# dictionary vs 2D array 【发布时间】:2021-12-02 01:00:37 【问题描述】:我有一个 5000 行 * 30 列的 Excel 工作表,我想将它们读入 C# 程序,然后通过查找行标题和列标题定期访问这些值。该程序将在普通笔记本电脑(16GB 内存)上运行。我应该使用字典词典来存储这些数据吗?如果是这样,是否更建议创建一个包含 5000 个较小字典的字典,每个字典具有 30 个键值对(即,行标题将是“外部”字典的键,列标题将是“内部”字典的键字典)还是 30 个字典,每个字典有 5000 个键值对?或者我应该创建一个二维数组,并将行标题和行索引对以及列标题和列索引对存储在 2 个较小的字典中?还是我需要担心这么多数据的内存/性能问题?
谢谢。
【问题讨论】:
您应该创建一个Model
类,其中 Properties 将是您的 30 列,其值将是 5000 行中的值。因此,您将只有一个 List<Model>
,其中包含 5000 个模型项。
5000 行对于现代计算机来说没什么,即使行很大。
如果您在 Excel 电子表格中对数据进行建模(不包括合并单元格或其他 非矩形 功能),并且您将通过行和列访问它们数字,那么您就有了 2D 数组的完美用例。再说一次,这个问题是基于意见的,可能很快就会结束(*** 对意见过敏)
字典是二进制散列,项目数为 Log(N)。如果您查找 30 个字典,则查找将是 30/2*(log(N/30) 并且您必须与 Log(N) 进行比较才能看到差异。直接列表中的查找是 N/2,这是平均值找到该项目之前的测试量。
【参考方案1】:
解释注释的示例。
你有一些 N 列 N 行的表:
您可以创建一个代表一个对象(一个实体)的类:
public class Person
并用属性填充它,这对于每个实体(您的 30 列)都是相似的:
public class Person
public string Name get; set;
public string Surname get; set;
public int Age get; set;
public string City get; set;
public string Gender get; set;
// and other of 30 columns
因此,表中的每一行代表某个人(在该示例中)。 5000 行 = 我们将有 5000 人。因为它们是相似的实体——我们可以将它们存储为集合或人员。我们可以使用(举个简单的例子):
Person[]
- 人员数组;
List<Person>
- 人员列表;
让我们想象一下,如何从表中读取数据并从中创建一个人员列表。
public void ReadTable(Table myTable) // We have Table with Rows and Columns
// Initializing our collection of Persons
List<Person> persons = new List<Person>;
// We need to read all 5000 rows, so iterating them
for (int i = 1; i <= myTable.Rows.Count; i++) // myTable.Rows.Count = 5000
// Creating a Person
Person person = new Person();
// Reading each cell value, accessing to it through RowIndex & ColumnIndex
// Row 1 Column 1 is Name
string name = myTable.Rows[i].Columns[1].Value.ToString(); // John
// Row 1 Column 2 is Surname
string surname = myTable.Rows[i].Columns[2].Value.ToString(); // Wick
// Row 1 Column 3 is Age
int age = int.Parse(myTable.Rows[i].Columns[3].Value); // 55
// Row 1 Column 4 is City
string city = myTable.Rows[i].Columns[4].Value.ToString(); // New York
// Row 1 Column 5 is Gender
string gender = myTable.Rows[i].Columns[5].Value.ToString(); // Male
//Received from table values we add to a Person:
person.Name = name;
person.Surname = surname;
person.Age = age;
person.City = city;
person.Gender = gender;
// And finally adding Person to a collection (list) of Persons:
persons.Add(person);
// And same would happen with other 5000 rows
因此,阅读后您将拥有包含 5000 个项目的 persons
列表。您可以操作它们、编辑、添加新的和删除现有的 - 随便什么。
【讨论】:
【参考方案2】:根据this,字典中一个元素的内存开销约为 20 字节。所以 5000 * 30 * 20 = 3000000 字节,或 3Mb,加上字典对象本身的几个 Kb。
由于这对于现代计算机来说微不足道,因此从内存的角度来看可能无关紧要。从性能的角度来看,这也可能无关紧要。
因此,如果您选择字典、锯齿状数组、二维数组或显式行对象,则应更多地从最容易使用的替代方案中确定。
如果所有单元格都具有相同的类型,则二维数组可能是最简单的选择。如果类型不同,为每列创建具有属性的 Model
或 Row
类可能最有用,这将有助于提供比简单的行/列更高级别的抽象。
【讨论】:
【参考方案3】:正如@JonasH 所回答的那样,任何现代系统都可以处理 5000 行,为结构定义模型是继续前进的好解决方案。另一方面,您也可以将您的 Excel 数据加载到 DataTable 对象中。 DataTable 易于使用,它允许以一致的格式将数据汇集到其中,嵌入其他允许进行排序、搜索等的属性。如果将来数据负载会增加,请继续创建模型。
【讨论】:
以上是关于C# 字典 vs 二维数组的主要内容,如果未能解决你的问题,请参考以下文章