Вопрос

У меня есть приложение, которому необходимо перебирать все строки в текстовых файлах размером более гигабайта.Некоторые из этих файлов содержат 10 или 100 миллионов строк.

Пример моего текущего (и синхронного) чтения выглядит примерно так...

  using (FileStream stream = new FileStream(args[0], FileMode.Open, FileAccess.Read, FileShare.Read)) {
    using (StreamReader streamReader = new StreamReader(stream)) {
      string line;
      while (!string.IsNullOrEmpty(line = streamReader.ReadLine())) {           
        //do stuff with the line string...
      }
    }
  }

Я прочитал кое-что о методах потоковой передачи асинхронного ввода-вывода .Net, и мне нужна некоторая помощь по двум конкретным вопросам, касающимся этой проблемы.

Во-первых, получу ли я повышение производительности за счет асинхронного чтения этих файлов, если мне нужна полная информация о каждой строке, которая обычно короткая, но разной длины (между каждой из строк в файле нет взаимосвязи)?

Во-вторых, как мне преобразовать приведенный выше код в асинхронное чтение, чтобы я мог обрабатывать каждую строку построчно, как я делаю сейчас?

Это было полезно?

Решение

Вместо того, чтобы делать чтение строки асинхронным, вы могли бы попробовать сделать чтение файла асинхронным.Это включает в себя весь код в вашем вопросе в одном рабочем делегате.

    static void Main(string[] args)
    {
        WorkerDelegate worker = new WorkerDelegate(Worker);
        // Used for thread and result management.
        List<IAsyncResult> results = new List<IAsyncResult>();
        List<WaitHandle> waitHandles = new List<WaitHandle>();

        foreach (string file in Directory.GetFiles(args[0], "*.txt"))
        {
            // Start a new thread.
            IAsyncResult res = worker.BeginInvoke(file, null, null);
            // Store the IAsyncResult for that thread.
            results.Add(res);
            // Store the wait handle.
            waitHandles.Add(res.AsyncWaitHandle);
        }

        // Wait for all the threads to complete.
        WaitHandle.WaitAll(waitHandles.ToArray(), -1, false); // for < .Net 2.0 SP1 Compatibility

        // Gather all the results.
        foreach (IAsyncResult res in results)
        {
            try
            {
                worker.EndInvoke(res);
                // object result = worker.EndInvoke(res); // For a worker with a result.
            }
            catch (Exception ex)
            {
                // Something happened in the thread.
            }
        }
    }

    delegate void WorkerDelegate(string fileName);
    static void Worker(string fileName)
    {
        // Your code.
        using (FileStream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read))
        {
            using (StreamReader streamReader = new StreamReader(stream))
            {
                string line;
                while (!string.IsNullOrEmpty(line = streamReader.ReadLine()))
                {
                    //do stuff with the line string...
                }
            }
        }
    }

Другие советы

Асинхронный шаблон называется BeginRead()/EndRead() .

Получите вы повышение или нет, во многом зависит от того, что еще происходит во время чтения.Есть ли что-то еще, что ваше приложение может делать во время ожидания результатов чтения?Если нет, то переход на асинхронный режим не сильно поможет...

Асинхронное чтение просто приведет к тому, что head будет искать больше для каждого блока.Вы получите больший прирост производительности за счет хорошей дефрагментации файлов в файловой системе и использования синхронного чтения.

Как уже указывалось, передача строчной обработки другим потокам должна дать толчок (особенно на многоядерных процессорах).

Если производительность сверхкритична, я бы рекомендовал изучить взаимодействие для FILE_FLAG_SEQUENTIAL_SCAN Видишь подробности здесь

Еще лучше написать крошечное приложение на C ++, которое просматривает файл с этим флагом, чтобы увидеть, повышает ли это производительность.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top