Оптимизация I/O операций для работы с большими текстовыми файлами (1Гб+) - C#
Формулировка задачи:
Доброго времени суток.
Подскажите каким образом можно оптимизировать I/O операций для работы с большими текстовыми файлами (1Гб+)
Мне поставили задачу считывать данные из файла, делить каждую строку на слова и далее записывать список слов в другой файл с указанием номеров строк где каждое из слов встречается в файле №1.
Человек давший задание предложил мне использовать другую структуру данных, чтобы оптимизировать чтение/запись. Какая из структур данных справиться с этой задачей лучше List<T>?
Буду благодарен за ссылки на статьи и литературу про оптимизацию I/O для текстовых файлов.
Класс представляющий слово
Вот метод в котором я построчно считываю файл и создаю список слов
Метод с помощью которого я записываю результат в другой файл
public class Word { public string Text { get; set; } public List<int> LineNumbers { get; set; } public Word() { LineNumbers = new List<int>(); } }
public List<Word> ReadFileAsync(string filePath) { // var watch = System.Diagnostics.Stopwatch.StartNew(); List<Word> words = new List<Word>(); int lineCount = 1; try { using (StreamReader sr = new StreamReader(filePath)) { string nextLine; while ((nextLine = sr.ReadLine()) != null) { AddWordFromLineToWordList(SplitLineIntoWords(nextLine), words, lineCount); lineCount++; } } } catch (Exception ex) { } // watch.Stop(); // var elapsedMs = watch.ElapsedMilliseconds; // Console.WriteLine(elapsedMs); return words; }
public async Task WriteAsync(string path, List<Word> words) { DeleteFile(path); CreateFile(path); words.Sort(new WordComparer()); foreach (Word word in words) { await WriteWordsAndLineNumbersAsync(path, word); } }
private async Task WriteWordsAndLineNumbersAsync(string path, Word word) { try { using (FileStream fs = new FileStream(path, FileMode.Append, FileAccess.Write, FileShare.Write, 4096, useAsync: true)) { using (StreamWriter sw = new StreamWriter(fs)) { await sw.WriteAsync(word.Text + " "); int size = word.LineNumbers.Count; for (int i = 0; i < size; i++) { if (i < size - 1) { await sw.WriteAsync(word.LineNumbers[i] + ", "); } else { await sw.WriteAsync(word.LineNumbers[i].ToString()); } } sw.Write(Environment.NewLine); } } } catch (Exception ex) { } }
Решение задачи: «Оптимизация I/O операций для работы с большими текстовыми файлами (1Гб+)»
textual
Листинг программы
static void Main(string[] args) { string str = "1 The the quick, brown fox. r fox jumped over the lazy dog dog.The1 the1 quick1, brown1 fox1. fox1 jumped1 over1 the1 lazy1 dog1 dog1."; Regex pattern = new Regex( @"( [A-Za-z0-9] ([A-Za-z0-9])* [A-Za-z0-9])", RegexOptions.IgnorePatternWhitespace); List<string> list1 = SplitLineIntoWords(str, pattern); List<string> list2 = SplitLineIntoWords2(str); for(int i = 0; i < list1.Count; ++i) { if(!list1[i].SequenceEqual(list2[i])) throw new Exception(); } Stopwatch sw1 = Stopwatch.StartNew(); list1 = SplitLineIntoWords(str, pattern); sw1.Stop(); Console.WriteLine($"SplitLineIntoWords {sw1.ElapsedTicks}"); Stopwatch sw2 = Stopwatch.StartNew(); list2 = SplitLineIntoWords2(str); sw2.Stop(); Console.WriteLine($"SplitLineIntoWords2 {sw2.ElapsedTicks}"); Console.ReadKey(); GC.KeepAlive(list1); GC.KeepAlive(list2); } public static unsafe List<string> SplitLineIntoWords2(string str) { List<string> list = new List<string>(); int index = 0; bool flag = false; int i = 0; fixed (char* ptr = str) { for(i = 0; i < str.Length; ++i) { int n = ptr[i]; if((n >= 'a' && n <= 'z') || (n >= 'A' && n <= 'Z') || (n >= '0' && n <= '9')) { if(!flag) { flag = true; index = i; } } else { if(flag && i - index > 1) { list.Add(new string(ptr, index, i - index).ToLower()); } flag = false; index = i; } } if(flag && i - index > 1) { list.Add(new string(ptr, index, i - index).ToLower()); } } return list; } public static List<string> SplitLineIntoWords(string lineText, Regex pattern) { List<string> lineWords = new List<string>(); foreach(Match m in pattern.Matches(lineText)) { lineWords.Add(m.Groups[1].Value.ToLower()); } return lineWords; } }
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д