2015-05-10 2 views
0

Я курсор загружаю файлы от 10k до 200k, поэтому я ищу некоторые повышения производительности здесь.C# OpenFileDialog улучшение производительности

Вот как я это делаю:

 List<string> myFiles = new List<string>(); 
     OpenFileDialog openFileDialog = new OpenFileDialog(); 
     openFileDialog.Multiselect = true; 
     openFileDialog.Filter = "Text files (*.txt)|*.txt|All files (*.*)|*.*"; 
     if (openFileDialog.ShowDialog() == true) 
     { 
      foreach (string filename in openFileDialog.FileNames) 
      { 
       myFiles.Add(filename); 

      } 
     } 
     string[] files = myFiles.ToArray(); 
     Splitter(files); 

     private void Splitter(string[] file) 
     { 
      try 
      { 
       tempDict = file 
        .SelectMany(i => File.ReadAllLines(i) 
        .SelectMany(line => line.Split(new[] { ' ', ',', '.', '?', '!', }, StringSplitOptions.RemoveEmptyEntries)))      
        .GroupBy(word => word) 
        .ToDictionary(g => g.Key, g => g.Count()); 
      } 
      catch (Exception ex) 
      { 
       Ex(ex); 
      } 
     } 

Я думал о том, чтобы Еогеасп pararell:

 Parallel.ForEach(openFileDialog.FileNames, filename => 
      { 
       mySpam.Add(filename); 
      }); 

Является ли это безопасно? Есть ли какие-либо улучшения в этом коде? Прямо сейчас, он становится отстающим, и программа «зависает» при загрузке этих файлов, поэтому было бы неплохо, если бы делали эти вещи «за сценой». Я использую WPF, и файлы загрузки начинаются после нажатия кнопки.

+1

Рассматривали ли вы переписывания решение стандартного алгоритма, а не с помощью Linq? Это поможет вам понять, какие узкие места и предоставить вам больше свободы в реализации оптимизации. Вы считаете все отдельные слова во всех файлах? – Dusan

+0

Кроме того, Linq обрабатывает все файлы одновременно, что также может привести к проблемам с памятью - и обработка всего сразу не требуется, вы должны обрабатывать файлы по одному и строить результат. – Dusan

+0

@ Dusan, поэтому я должен изменить метод Splitter? Не думал о проблемах там .. хм. –

ответ

0

Вы можете попробовать эти вещи:

  1. Как предложил Душан, преобразовать его в стандартный алгоритм, так что вы можете время различные части алгоритма и посмотреть, что занимает больше времени.

  2. Переместите обработку в фоновый поток вместо потока пользовательского интерфейса. Это будет поддерживать ваш интерфейс.

  3. Попробуйте Parallel.For/Parallel.ForEach или Select.AsParallel (Plinq) для параллельного выполнения действий. Помните о безопасности нитей. Также, когда вы будете выполнять эту операцию параллельно, количество ядер процессора и пропускная способность диска будут иметь значение.

  4. Посмотрите, поможет ли Regex вместо ручной манипуляции с строкой.

1

Хм. Вы, наверное, на узкие места ввода-вывода, однако, вы можете получить более высокую скорость за счет распараллеливания часть запроса:

file 
    //ReadLines is non-greedy equiv of ReadAllLines 
    //best to do this on a single thread... 
    .SelectMany(i => File.ReadLines(i)) 
    //now go parallel. 
    .AsParallel() 
    .SelectMany(line => line.Split(new[] { ' ', ',', '.', '?', '!', }, 
         StringSplitOptions.RemoveEmptyEntries))     
    .GroupBy(word => word) 
    .ToDictionary(g => g.Key, g => g.Count()); 
+1

Да, я также думаю, что ЗАГРУЗКА того большого количества файлов - это большая проблема, а не сама инструкция. Но я могу ошибаться. –

+1

Если у вас нет удивительной части памяти, вы не ускорите загрузку файлов с помощью параллелизма. Вы просто вызовете крушение диска, которое замедлит ваши чтения, а не ускорит их. По моему опыту, вы получите лучшую производительность, выполнив чтение IO из одного потока. – spender

+0

Это легко проверить, перемещая '.AsParallel()' выше в запросе ... – spender