Возможно ли ускорение ввода-вывода python?

Рассмотрим эту программу python:

import sys

lc = 0
for line in open(sys.argv[1]):
    lc = lc + 1

print lc, sys.argv[1]

Запустив его в моем текстовом файле на 6 ГБ, он завершится через ~ 2 минуты.

Вопрос: возможно ли ускорение?

Обратите внимание, что то же время требуется:

wc -l myfile.txt

поэтому, я подозреваю, что андер для моего вопроса - просто "нет".

Обратите внимание также, что моя настоящая программа делает что-то более интересное, чем просто подсчет строк, поэтому, пожалуйста, дайте общий ответ не трассировки строки (например, сохранение метаданных в файле в файле )

PS: Я отметил "linux" этот вопрос, потому что меня интересуют только конкретные ответы на Linux. Не стесняйтесь давать OS-агностик или даже ответы других ОС, если они у вас есть.

См. также последующий вопрос

Ответ 1

Вы не можете получить скорость выше максимальной скорости чтения диска.

Чтобы достичь максимальной скорости диска, вы можете использовать следующие два совета:

  • Прочитайте файл с большим буфером. Это может быть закодировано "вручную" или просто с помощью io.BufferedReader(доступно в python2.6 +).
  • Повторите подсчет новой строки в другом потоке.

Ответ 2

Бросьте аппаратное обеспечение на проблему.

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

Изменить: Еще одна хорошая точка gs; вы также можете использовать конфигурацию RAID, чтобы повысить скорость. Это можно сделать либо с помощью hardware, либо программного обеспечения (например, OS X, Linux, Windows Server и т.д.).


Управляющее уравнение

(Amount to transfer) / (transfer rate) = (time to transfer)

(6000 MB) / (60 MB/s) = 100 seconds

(6000 MB) / (125 MB/s) = 48 seconds


Аппаратные решения

Предполагается, что ioDrive Duo является самым быстрым решением для корпоративных настроек и "будет доступен в апреле 2009 года".

Или вы можете проверить жесткий диск WD Velociraptor (10000 об/мин).

Кроме того, я слышал, что Seagate Cheetah является хорошим вариантом (15 000 об/мин с устойчивой скоростью передачи 125 МБ/с).

Ответ 3

Трюк заключается не в том, чтобы заставить электроны двигаться быстрее (что трудно сделать), а для того, чтобы сделать больше работы за единицу времени.

Во-первых, убедитесь, что ваш 6-гигабайтный файл считывается с привязки ввода-вывода, а не с привязкой к ЦП.

Если он связан с I/O, рассмотрим шаблон проектирования "Fan-Out".

  • Родительский процесс порождает кучу детей.

  • Родитель читает файл 6Gb и передает строки дочерним элементам, записывая их в свои STDIN-каналы. Время чтения 6 ГБ останется постоянным. Задание строки должно включать как можно меньшую родительскую обработку. Следует использовать очень простые фильтры или подсчеты.

    Труба - это канал в памяти для связи. Это общий буфер с читателем и писателем.

  • Каждый ребенок читает строку из STDIN и выполняет соответствующую работу. Каждый ребенок должен, вероятно, написать простой файл на диске с итоговыми (суммированными, уменьшенными) результатами. Позже результаты в этих файлах могут быть объединены.

Ответ 4

plain "no".

Вы достигли максимальной скорости диска.

Я имею в виду, вы могли бы mmap файл или прочитать его в двоичных фрагментах и ​​использовать .count('\n') или что-то еще. Но это вряд ли даст значительные улучшения.

Ответ 5

Если вы предполагаете, что диск может читать 60 МБ/с, вам понадобится 6000/60 = 100 секунд, что составляет 1 минуту 40 секунд. Я не думаю, что вы можете получить быстрее, потому что диск является узким местом.

Ответ 6

как говорили другие - "нет"

Почти все ваше время потрачено на ожидание ввода-вывода. Если это то, что вам нужно делать не один раз, и у вас есть машина с множеством бара, вы можете сохранить файл в памяти. Если ваша машина имеет 16 ГБ оперативной памяти, у вас будет 8 ГБ в /dev/shm, чтобы играть с.

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

Ответ 7

Обратите внимание, что Python I/O реализован на C, поэтому нет большой удачи, ускоряя его дальше.

Ответ 8

2 минуты звучат о праве читать весь файл 6gb. На самом деле, вы не можете сделать так, чтобы алгоритм или ОС ускорили работу. Я думаю, у вас есть два варианта:

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

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