47 / 46 / 26
Регистрация: 16.06.2012
Сообщений: 177
1

Сравнение двух огромных (!) файлов

16.10.2013, 10:50. Показов 2779. Ответов 4
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Привет. Потребовалось сравнивать текстовые файлы (несколько файлов сравниваются с другим):
Файл 1.txt содержит 1 миллион строк.
Файл 2.txt содержит 10 миллионов строк.
Файл 3.txt содержит 5 миллионов строк.
Все их нужно сравнить с файлом keys.txt, который содержит 11 тысяч строк.
Если в открытом файле текущая строка совпадает с одной из строк в файле keys.txt, то записывать её в выходной файл.
Если сравнивать "в лоб", получается около 150 миллиардов операций. Сравнение в один поток даёт 1-3 операции за 1 мс. Подскажите, как уменьшить время сравнения.

Добавлено через 10 минут
p.s. Сейчас сравниваю так:
Pascal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
procedure Thread.saveStr(sToSave: string);
var
  fOut: TextFile;
begin
  AssignFile(fOut, 'output.txt');
  if FileExists(ExtractFilePath(Paramstr(0)) + 'output.txt') then
    Append(fOut)
  else
    Rewrite(fOut);
  writeLn(fOut, sToSave);
  CloseFile(fOut);
end;
 
//..
 
function Thread.checkKeys(sLine: string): boolean;
var
  SR: TStreamReader;
  line: string;
begin
  Result := false;
  SR := TStreamReader.Create(sKeyFile);
  try
    while (not(SR.EndOfStream)) and (not(Result))do
      begin
        line := SR.ReadLine;
        if LowerCase(line) = LowerCase(sLine) then
          begin
            saveStr(sLine);
            inc(iMatch);
            Result := true;
          end;
      end;
  finally
    SR.Free;
  end;
end;
 
//..
// В цикле по файлам прохожусь
AssignFile(fInput, tsFiles[iCurFile]);
Reset(fInput);
while not(EOF(fInput)) do
  begin
    readLn(fInput, sInput);
    checkKeys(sInput);
  end;
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
16.10.2013, 10:50
Ответы с готовыми решениями:

Сравнение двух текстовых файлов
Имеется 2 файла txt. Нужно сравнить эти файлы.Они почти идентичны, но в начале первого файла есть...

Сравнение двух таблиц, с разных вордовских файлов
Всем доброго времени суток, уважаемые знатоки, подскажите пожалуйста каким образом или возможно ли...

Сравнение даты изменения двух файлов с использованием edit
Подскажите пожалуйста долгое время бьюсь над способом сравнения двух одинаковых файлов. в двух...

Сравнение двух звуковых файлов.
Ну начну: задача стоит следующая - есть эталон звука (как я понимаю записанный в WAV-файл),...

4
13095 / 5876 / 1706
Регистрация: 19.09.2009
Сообщений: 8,808
16.10.2013, 16:40 2
Скорость падает из-за того, что для проверки каждой строки заново с диска читается файл ключей. Файл ключей надо полностью в память загрузить - до начала проверок. Загрузить можно в экземпляр TStringList, например. Тогда проверка строки будет выглядеть так:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var
  Sl : TStringList;
  Line : String;
begin
  Sl := TStringList.Create;
...
  //Поиск строки Line в списке Sl без учёта регистра букв.
  if Sl.IndexOf(Line) <> -1 then begin
    //Строка Line найдена в списке Sl.
    //...
    //...
    //...
  end;
...
  FreeAndNil(Sl);
end;
0
47 / 46 / 26
Регистрация: 16.06.2012
Сообщений: 177
16.10.2013, 18:09  [ТС] 3
Цитата Сообщение от Mawrat Посмотреть сообщение
Скорость падает из-за того, что для проверки каждой строки заново с диска читается файл ключей. Файл ключей надо полностью в память загрузить - до начала проверок. Загрузить можно в экземпляр TStringList, например. Тогда проверка строки будет выглядеть так:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var
  Sl : TStringList;
  Line : String;
begin
  Sl := TStringList.Create;
...
  //Поиск строки Line в списке Sl без учёта регистра букв.
  if Sl.IndexOf(Line) <> -1 then begin
    //Строка Line найдена в списке Sl.
    //...
    //...
    //...
  end;
...
  FreeAndNil(Sl);
end;
Спасибо, но! В файле ~11 тысяч строк. Что, если больше? А если строки длинные? (32 символа + каретка) * 11000. Память она не резиновая. На stackoverflow уже ответили. Использую TDictionary<string, boolean> скорость возросла в сотни раз.
0
993 / 521 / 102
Регистрация: 19.03.2013
Сообщений: 3,113
Записей в блоге: 19
16.10.2013, 18:20 4
Можно еще разбить большие файлы на файлы поменьше, сделать отдельные потоки для каждого файла и запускать их параллельно.
0
3174 / 1933 / 312
Регистрация: 27.08.2010
Сообщений: 5,131
Записей в блоге: 1
16.10.2013, 18:31 5
Стандартное решение - использование Aho–Corasick string matching algorithm.

Этот алгоритм используют многие AV (с сотнями тысяч сигнатур в базе). В отличие от поиска в словаре за квадратичное время, время работы AC-автомата линейно.

В одной из моих программ, таким образом в бинарных файлах отыскиваются вхождения первых 100,000 простых чисел. Думаю, это вполне сравнимо с вашими 11,000 строк.
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
16.10.2013, 18:31
Помогаю со студенческими работами здесь

Сравнение файлов
Здравствуйте, уважаемые специалисты. Собственно сам вопрос заключается в побайтовом сравнении...

Сравнение текстовых файлов.
Добрый день! Такое вот задание. Даны 2 текстовых файла. Проверить, все ли строки из 1-го...

Сравнение больших файлов
Даются два XLS(CSV) файла, требуется из 1 файла вытащить из поля N - номера телефонов и сравнить их...

Сравнение 2 xls файлов
Ребят прошу помощь! написал программу на вывод двух файлов xls в DBGrid1 и DbGrid2 и добавил еще...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
5
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2023, CyberForum.ru