Python - масштабируемость относительно времени выполнения и использования памяти важна - PullRequest
0 голосов
/ 27 февраля 2019

У меня есть скрипты Python для фильтрации больших данных в CSV-файле.Требование требует учета масштабируемости в отношении времени выполнения и использования памяти.

Я написал 2 скрипта, оба прекрасно работают для фильтрации данных.Что касается масштабируемости, я решил использовать генератор Python, потому что он использует итератор и не сохраняет много данных в памяти.

Когда я сравнил время выполнения двух сценариев, я обнаружил следующее:

сценарий 1 - использовать генератор - больше времени - 0,0155925750732s

def each_sentence(text):
    match = re.match(r'[0-9]+', text)
    num = int(text[match.start():match.end()])
    if sympy.isprime(num) == False:
        yield text.strip()

with open("./file_testing.csv") as csvfile:
    for line in csvfile:
        for text in each_sentence(line):
            print(text)

сценарий 2- использовать сплит и без генератора - занимать меньше времени - 0,00619888305664

with open("./file_testing.csv") as csvfile:
for line in csvfile:
    array = line.split(',')
    num = int(array[0])
    if sympy.isprime(num) == False:
        print line.strip()

Чтобы выполнить требование, нужно ли использовать генератор Python?или какие-либо предложения или рекомендации?

Ответы [ 2 ]

0 голосов
/ 27 февраля 2019

Разделите ваш анализ на два дискретных результата регулярного выражения: маленький результат с 10 значениями и большой результат с 10 000 000 значений.Этот вопрос о среднем len() из match, столько же, сколько о len() из csvfile.

с небольшим повторным результатом - 10 байтов

1-йкодовый блок будет иметь более медленное время выполнения и относительно низкое использование памяти .

2-й кодовый блок будет иметь более быстрое время выполнения, а также относительно низкое использование памяти .

С большим результатом re - 10 000 000 байтов

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

2-й кодовый блок будет иметьболее быстрое время выполнения и очень большое использование памяти.

Итог:

Если предполагается построить функцию с учетом времени выполнения и памяти, тогда функция yieldбезусловно, лучший путь, когда проблема требует масштабируемого решения с различными размерами результатов.

Еще один вопрос о масштабируемости: что, если результат равен None?Я бы немного изменил код ниже:

def each_sentence(text):
    match = re.match(r'[0-9]+', text)
    if match != None:
        num = int(text[match.start():match.end()])
        if sympy.isprime(num) == False:
            yield text.strip()

with open("./file_testing.csv") as csvfile:
    for line in csvfile:
        for text in each_sentence(line):
            print(text)
0 голосов
/ 27 февраля 2019

Чтобы соответствовать требованию, нужно ли мне использовать генератор питона?

Нет, вы этого не делаете.Сценарий 1 не имеет смысла.Генератор всегда выполняется один раз и возвращает один результат в первой итерации.

Любые предложения или рекомендации?

Вам необходимо изучить три вещи: сложность, распараллеливание икеширование.

  • Сложность в основном означает «если я удваиваю размер входных данных (CSV-файл), мне нужно дважды? Или четыре раза? Или что?»

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

  • Кэширование важно.Вещи становятся намного быстрее, если вам не нужно все время заново создавать, но вы можете повторно использовать уже сгенерированный материал.

Основной цикл for line in csvfile: ужеочень хорошо масштабируется, если файл csv не содержит слишком длинных строк.

Сценарий 2 содержит ошибку: если первая ячейка в строке не является целочисленной, то int(array[0]) вызовет ошибку значения.

Функция isprime, вероятно, является "горячей точкой"в вашем коде, так что вы можете попытаться распараллелить его с несколькими потоками или подпроцессами.

...