2015-01-29 1 views
1

Я знал, что функция будет включать в себя много обработки данных, но я не думал, что это закончит тем, что нужно обработать minuets.Вложенная функция Loop, использующая minuets для запуска, в любом случае для повышения эффективности?

В данной функции подается зубчатый 2D-массив, состоящий из абзацев> Предложения, которые сделаны из текстового файла, подаваемого пользователем, поэтому могут быть массивными. Он принимает этот массив и сравнивает каждое предложение друг с другом и сохраняет оценку между каждым предложением, которое является числом общих слов.

Это берет навсегда, и я честно не думал, что так будет.

Мой основной тестовый текст длится всего 181, но это означает 32,7 тысячи значений, полученных в 2D-массиве.

Эта матрица значений затем используется для вычисления и выбора наиболее «релевантных» предложений из каждого абзаца и других вещей.

Текст предложения 181 занимает 1 мин 15 секунд для обработки, текст из 70 предложений занимает 35 секунд, но это основано на количестве предложений не слов, но оно дает вам представление. Я боюсь думать, сколько времени займет фактический документ.

Функция в вопросе:

protected void Intersection2DArray() 
    { 
     mainSentenceCoord = -1; 
     for (int x1 = 0; x1 < results.Length; x1++) 
     { 
      for (int x2 = 0; x2 < results[x1].Length; x2++) 
      { 
       var mainSentencesWords = wordSplit(results[x1][x2]); 
       secondarySentenceCoord = -1; 
       mainSentenceCoord++; 

       for (int y1 = 0; y1 < results.Length; y1++) 
       { 
        for (int y2 = 0; y2 < results[y1].Length; y2++) 
        { 
         var secondarySentencesWords = wordSplit(results[y1][y2]); 
         int commonElements = mainSentencesWords.Intersect(secondarySentencesWords).ToList().Count(); 
         secondarySentenceCoord++; 
         intersectionArray[mainSentenceCoord, secondarySentenceCoord] = commonElements; 
        } 
       } 
      } 
     } 
    } 

wordSplit функция:

 protected List<String> wordSplit(string sentence) 
     { 
      var symbols = "£$€#&%+-."; 
      var punctuationsChars = Enumerable.Range(char.MinValue, char.MaxValue - char.MinValue) 
             .Select(i => (char)i) 
             .Where(c => char.IsPunctuation(c)) 
             .Except(symbols) 
             .ToArray(); 

      var words = sentence.Split(punctuationsChars) 
          .SelectMany(x => x.Split()) 
          .Where(x => !(x.Length == 1 && symbols.Contains(x[0]))) 
          .Distinct() 
          .ToList(); 
      return words; 
     } 

Первоначально я хотел сделать этот раскол, используя одну Regex линию, но не понять его, что может сделать это быстрее.

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

Edit: Использование Moby диска предложения Heres мой новый мгновенный код:

Слово Split функция, которая вызывается один раз сейчас и возвращает список Список

public List<List<string>> createWordList() 
    { 
     List<List<string>> wordList = new List<List<string>>(); 
     var symbols = "£$€#&%+-."; 
     var punctuationsChars = Enumerable.Range(char.MinValue, char.MaxValue - char.MinValue) 
            .Select(i => (char)i) 
            .Where(c => char.IsPunctuation(c)) 
            .Except(symbols) 
            .ToArray(); 

     for (int x1 = 0; x1 < results.Length; x1++) 
     { 
      for (int x2 = 0; x2 < results[x1].Length; x2++) 
      { 
       var words = results[x1][x2].Split(punctuationsChars) 
              .SelectMany(x => x.Split()) 
              .Where(x => !(x.Length == 1 && symbols.Contains(x[0]))) 
              .Distinct() 
              .ToList(); 
       wordList.Add(words);      
      } 
     } 
     return wordList; 
    } 

И теперь уже супер тонкий перекрестков

protected void intersectionMatrix() 
    { 
     List<List<string>> wordList = createWordList(); 
     mainSentenceCoord = -1; 
     for (var x = 0; x < wordList.Count; x++) 
     { 
      secondarySentenceCoord = -1; 
      mainSentenceCoord++; 
      for (var y = 0; y < wordList.Count; y++) 
      { 
       secondarySentenceCoord++; 
       intersectionArray[mainSentenceCoord, secondarySentenceCoord] = wordList[x].Intersect(wordList[y]).Count(); 
      } 
     } 
    } 
+0

Вы в основном сравниваете предложения X из одного документа с предложениями Y от другого, которые будут выполнять сравнения X * Y, и поскольку каждое сравнение само по себе является довольно дорогостоящим, да, для этого потребуется время. Поскольку вы делаете общие слова, любой шанс, что вы могли бы предварительно обработать один документ в словаре с ключом по слову и отработать? –

+0

Сравнивая предложения внутри одного документа друг с другом, а затем каждое предложение заканчивается оценкой, представляющей, как она выступает против других. Не знаю, хорошо ли я объяснил. Я чувствую проблему с конденсированием массива, даже если он должен был затем сравнить массив со словарем, это будет оценка, основанная на оценке предложения, которая будет потеряна. – Vereonix

+1

Я голосую, чтобы закрыть этот вопрос как не относящийся к теме, потому что он более подходит для codereview.stackexchange.com –

ответ

4

обновление См в конце:

Существуют некоторые «низко висящие плоды» здесь, которые могли бы ускорить его много с из изменения алгоритма себя:

  1. wordSplit() пересчитывает «punctuationsChars» каждый раз, когда она вызывается. Сделайте это раньше.
  2. Вы вызываете wordSplit() для того же предложения число N^2 раз вместо N числа раз, так как оно находится как в внешнем (x1, x2), так и в внутреннем (y1, y2). Вам нужно всего лишь разделить 181 предложение, а не 181^2 количество предложений. Таким образом, вместо этого, прокрутите результаты, вызовите wordSplit один раз на каждое предложение и сохраните этот результат. Если это занимает слишком много памяти, загляните в memoization (http://en.wikipedia.org/wiki/Memoization), хотя я думаю, что с вами все будет в порядке, так как это приведет только к еще 1 копированию текста.
  3. Вам не нужен ToList() после Intersect(). Это создает список, который вы не используете.

Я смущен относительно значений mainSentenceCoord и secondarySentenceCoord. Каковы размеры результирующего объекта intersectionArray?

OMG! # 1 это! Это ускорилось в 80 раз. Посмотрите на этой линии:

Enumerable.Range(char.MinValue, char.MaxValue - char.MinValue) 

char.MaxValue является 65536. Таким образом, если N = 181, вы зацикливание 181 х 181 х 65536! Я просто запустил профайлер, чтобы подтвердить это: 98,4% времени процессора тратится на вызовы ToArray() в wordSplit.

+0

Вы, мой мозг с обновлением, я пытаюсь обвести вокруг него, что касается переменных координат и intersectionArray, это 2D-массив, который содержит номер предложения^2, поэтому я могу пойти и увидеть значение пересечения из любых предложений, визуализировал его как одну из тех таблиц таблиц раз, где вы можете идти и вниз до 3x5 и т. д. Мне нужны все эти значения, так как он позволяет мне анализировать, например, обычные слова в абзаце или что-то в этом роде. Я пытаюсь понять обновление eureka, которое вы добавили, хотя в отношении того, где я бы разместил/заменил – Vereonix

+0

Я не собираюсь делать вид, что понимаю, что делает эта строка «enumerable.range», но я реализовал все, что вы предлагаете, и святое сияние теперь мгновение. Я обновил свой вопрос, чтобы показать, как я его сейчас, спасибо! – Vereonix

 Смежные вопросы

  • Нет связанных вопросов^_^