Получение таймаутов для огромных массивов - PullRequest
0 голосов
/ 19 марта 2020

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

def textQueries(sentences, queries)
  queries.map { |query|
    index_arr = []
    sentences.map.with_index { |sentence, index|
      sentence_arr = sentence.split(' ')
      if query.split(' ').all? { |qur| sentence_arr.include?(qur) }
        index_arr << index
      end
    }
    index_arr << -1 if index_arr.empty?
    puts index_arr.join " "
  }
end

Example inputs :
**Sentences**:
it go will away
go do art
what to will east
**Queries**
it will
go east will
will

**Expected Result**
0
-1
0 2

1 Ответ

4 голосов
/ 19 марта 2020

На первый взгляд я вижу несколько оптимизаций:

  1. В настоящее время вы разделяете каждое предложение для каждого запроса. Ваш пример данных имеет 3 предложения и 3 запроса. Это означает, что каждое предложение разделяется 3 раза (один раз для каждого запроса). Поскольку результат не зависит от запроса, вы должны сделать это заранее. Каждое предложение следует разбивать только один раз.

  2. В настоящее время вы используете sentences.map для итерации предложений, но не фиксируете результат. Вы используете его только для целей итерации и результаты pu sh до index_arr. map создает новый массив, который вы не используете, то есть вы жуете память, которую можно использовать в другом месте. Это можно изменить на each, что гораздо эффективнее, если вы не используете возвращаемое значение.

  3. Код query.split(' ').all? { |qur| sentence_arr.include?(qur) } не совсем оптимальный, так как он начинает искать указанное c слово с начала sentence_arr каждый раз. Проверка того, является ли определенная коллекция подмножеством или надмножеством другой коллекции, - это то, где Set часто сияет.

Учитывая все вышесказанное, следует быть намного быстрее:

require 'set'

def text_queries(sentences, queries)
  sentences = sentences.map { |sentence| Set.new(sentence.split(' ')) }

  queries.map do |query|
    query = Set.new(query.split(' '))

    indexes = sentences.each_index.select { |index| sentences[index] >= query }
    indexes << -1 if indexes.empty?

    indexes
  end
end

Примечание: Если вы решили вывести значения на консоль (как показано в вопросе):

puts indexes.join(' ')

Тогда Нет смысла использовать queries.map, поскольку будет возвращен массив со значениями nil (puts всегда возвращает nil). Измените map на each в этом сценарии.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...