我有一个预采访任务,我已经完成并且解决方案有效,但由于使用了TADODataset,我被标记了并没有接受采访。我基本上导入了一个填充数据集的CSV文件,数据必须以特定的方式处理,所以我使用数据集的过滤和排序来确保数据按我想要的方式排序然后我做了while循环中的逻辑处理。收到的反馈说这很糟糕,因为对于大文件来说这会很慢。
我的主要问题是,如果使用内存数据集处理大型文件的速度很慢,那么从csv文件访问信息的更好方法是什么。我应该使用字符串列表还是类似的东西?
答案 0 :(得分:4)
这实际上取决于任务的“大”和可用资源(在本例中为RAM)。
“收到的反馈说这很糟糕,因为对于大文件来说这很慢。”
CSV文件通常用于移动数据(在大多数情况下我遇到的文件大约是1MB +高达~10MB,但这并不是说其他人不会以CSV格式转储更多数据)而不用担心太多(如果有的话)关于进口/出口,因为它非常简单。
假设您有一个80MB的CSV文件,现在这是一个你想要处理的文件,否则(取决于你的处理)你可以吃掉数百MB的RAM,在这种情况下我会做的是:
while dataToProcess do begin
// step1
read <X> lines from file, where <X> is the max number of lines
you read in one go, if there are less lines(i.e. you're down to 50 lines and X is 100)
to process, then you read those
// step2
process information
// step3
generate output, database inserts, etc.
end;
在上面的例子中,你没有将80MB的数据加载到RAM中,而只加载几百KB,其余的用于处理,即链接列表,动态插入查询(批量插入)等。
“......但由于使用了TADODataset,我被标记下来并没有接受采访。”
我并不感到惊讶,他们可能会想看看你是否能够在现场创建算法并提供简单的解决方案,但不使用“现成的”解决方案。
他们可能会考虑使用动态数组并创建一个(或多个)排序算法。
“我应该使用字符串列表还是类似的东西?”
回应可能是一样的,我认为他们想看看你是如何“工作”的。
答案 1 :(得分:0)
面试官是对的。
任何中型文件的正确,可扩展和最快的解决方案是使用“外部排序”。
“外部排序”是一个2阶段过程,第一阶段是将每个文件拆分为可管理和排序的较小文件。第二阶段是将这些文件合并回一个已排序的文件,然后逐行处理。
对于任何超过200,000行的CSV文件,它都非常有效。可以控制进程运行的内存量,从而可以消除内存不足的危险。
我已经实现了许多这样的排序过程,在Delphi中会推荐TStringList,TList和TQueue类的组合。
祝你好运