我正在使用.NET 4.5在C#中编写应用程序。我的应用程序读取和写入由硬件设备使用的二进制文件。该文件正好是5,000,000字节,由100,000个50字节“块”组成。每个50字节块将包含一个ASCII编码的字符串(可能只是一个空字符串)。设备需要文件布局,以便只需确定偏移量(索引* 50个字节然后读/写下50个字节)即可访问任何字符串。
我的WinForms应用程序需要能够:
注意事项:
所以我需要一个数据结构来保存文件中的所有数据,我很难在字典,列表或数组之间做出决定。鉴于上面的警告,我不认为将任何数据结构直接绑定到UI是一个可行的解决方案。所以我认为我需要在该数据结构和列表框之间需要大量代码才能实现某种伪绑定。如果是这种情况,从功能的角度来看哪个数据结构(字典,列表,数组,其他)是最有用的,并提供最佳折衷方案:使用此大小的数据集(100,000个字符串,最多50个ASCII字符)的速度每个)?
答案 0 :(得分:3)
如果性能至关重要,最好的解决方法就是测试它。编写一个快速而肮脏的应用程序,以三种方式执行关键任务,然后将其包装在一个循环中,完成10,000次,并查看哪个更快。
答案 1 :(得分:3)
字典在这里似乎没有必要,因为你没有任何密钥来索引你的数据 列表适用于添加/删除项目,但显然也不需要这样做 所以我会去一个字符串数组
编辑:重新考虑存在的多个空字符串,如果空字符串与填充字符串的比率不低,我可以建议可能的优化。
我们可以使用整数数组作为映射而不是仅包含填充字符串的字典
警告:需要测试
int[] keys = new int[100]; // Just 100 to test the idea
Dictionary<int, string> data = new Dictionary<int, string>();
AddItem(keys, 32, data, "Position 32 34567890123456789012345678901234567890");
AddItem(keys, 40, data, "Position 40 34567890123456789012345678901234567890");
AddItem(keys, 10, data, "Position 10 34567890123456789012345678901234567890");
AddItem(keys, 25, data, "Position 25 34567890123456789012345678901234567890");
AddItem(keys, 99, data, "Position 99 34567890123456789012345678901234567890");
AddItem(keys, 0, data, "Postion 00 234567890123456789012345678901234567890");
AddItem(keys, 18, data, "Position 18 34567890123456789012345678901234567890");
foreach(int x in keys)
{
if(x == 0)
Console.WriteLine("Empty string");
else
Console.WriteLine(data[x]);
}
void AddItem(int[] keys, int keyPos, Dictionary<int, string> data, string message)
{
int count = data.Count;
data.Add(count, message);
keys[keyPos] = count;
}
void RemoveItem(int[] keys, int keyPos, Dictionary<int, string> data)
{
int x = keys[keyPos];
data.Remove(x);
keys[keyPos] = 0;
}
void UpdateItem(int[] keys, int keyPos, Dictionary<int, string> data, string message)
{
int x = keys[keyPos];
data[x] = message;
}
答案 2 :(得分:1)
即使有100,000个条目,我也不认为你需要过多担心性能。 (编辑:我的意思是,当涉及到I / O或数据更改时的性能。您可能会遇到GUI绑定问题)
将其编程为最简单的方法,使您最容易对业务逻辑和GUI绑定进行更改。或许甚至可以考虑创建一个自己的类,只需用List
(或Array
或其他任何东西)包含GUI的标准公共接口来隐藏这个实现细节。
一旦您的GUI运行并且所有I / O运行正常(理想情况下,有一些不错的单元测试套件),那么您可以开始基准测试/分析并找到瓶颈所在。
编辑:考虑到您的要求,这个自定义/包装数据结构可能是理想的。它可以主动了解您数据的某些方面。例如,在加载/读取时,它可以检查新字符串是否有空间,因此当用户添加更多字符串时,您已经知道是否可以。它可以维护HashSet
使用过的唯一字符串,因此您可以对重复的字符串进行很好的O(1)查找,依此类推。
答案 3 :(得分:0)
实际上,字典在这里最适合存储数据。关键是存储的字符串,值将是它的位置。您可以按字典的大小跟踪您的可用空间。
对于列表框,首先将字典转换为数组,然后使用该数组作为列表框的后备存储。这将是您在应用程序启动时支付的一次性速度惩罚,但是您可以通过UI响应获得更快的速度并满足底层数据存储的其他要求。
在字典上执行添加/删除操作,快速处理重复检查,如果更改基础字典而不是重建数组,则可以快速直接更新数组。