Чтение Очень Большого Текстового Файла Одной Строки
у меня 30МБ .txt файл, с один строка (30 Млн. Цифр)
К сожалению, каждый метод, который я пробовал (mmap.read()
, readline()
, выделяя 1 ГБ ОЗУ, для циклов) занимает 45+ минут, чтобы полностью прочитать файл.
Каждый метод, который я нашел в интернете, кажется, работает на том, что каждая строка мала, поэтому потребление памяти составляет только самую большую строку в файле. Вот код, который я с помощью.
start = time.clock()
z = open('Number.txt','r+')
m = mmap.mmap(z.fileno(), 0)
global a
a = int(m.read())
z.close()
end = time.clock()
secs = (end - start)
print("Number read in","%s" % (secs),"seconds.", file=f)
print("Number read in","%s" % (secs),"seconds.")
f.flush()
del end,start,secs,z,m
кроме разделения числа от одной строки до разных строк; чего я бы предпочел не делать, есть ли более чистый метод, который не потребует большей части часа?
кстати, не обязательно использовать текстовые файлы.
у меня есть: Windows 8.1 64-бит, 16GB RAM, Python 3.5.1
3 ответов
чтение файла происходит быстро (
with open('number.txt') as f:
data = f.read()
преобразование строки из 30 миллионов цифр в целое число, это медленно:
z=int(data) # still waiting...
если вы храните число как необработанные двоичные данные большого или малого конца, то int.from_bytes(data,'big')
- это гораздо быстрее.
если я правильно сделал математику (Примечание _
означает "ответ последней строки" в интерактивном интерпретаторе Python):
>>> import math
>>> math.log(10)/math.log(2) # Number of bits to represent a base 10 digit.
3.3219280948873626
>>> 30000000*_ # Number of bits to represent 30M-digit #.
99657842.84662087
>>> _/8 # Number of bytes to represent 30M-digit #.
12457230.35582761 # Only ~12MB so file will be smaller :^)
>>> import os
>>> data=os.urandom(12457231) # Generate some random bytes
>>> z=int.from_bytes(data,'big') # Convert to integer (<1s)
99657848
>>> math.log10(z) # number of base-10 digits in number.
30000001.50818886
редактировать: к вашему сведению, моя математика была неправильной, но я ее исправил. Спасибо за 10 upvotes не замечая :^)
текстовый файл 30 МБ не должен занимать много времени для чтения, современные жесткие диски должны быть в состоянии сделать это менее чем за секунду (не считая времени доступа)
использование стандартного файла python IO должно работать нормально в этом случае:
with open('my_file', 'r') as handle:
content = handle.read()
С помощью этого на моем ноутбуке дает раз гораздо меньше, чем второй.
однако преобразование этих 30 МБ в целое число является вашим узким местом,
поскольку python не может представить это с помощью long
тип данных.
Вы можете попробуйте с десятичным модулем, однако он в основном предназначен для арифметики с плавающей запятой.
кроме того, конечно, есть numpy, который может быть быстрее (и так как вы, вероятно, захотите сделать некоторую работу с номером позже, имело бы смысл использовать такую библиотеку).
я использовал модуль gmpy2 для преобразования строки в число.
start = time.clock()
z=open('Number.txt','r+')
data=z.read()
global a
a=gmpy2.mpz(data)
end = time.clock()
secs = (end - start)
print("Number read in","%s" % (secs),"seconds.", file=f)
print("Number read in","%s" % (secs),"seconds.")
f.flush()
del end,secs,start,z,data
он работал за 3 секунды, намного медленнее, но, по крайней мере, он дал мне целое значение.
спасибо всем за ваши бесценные ответы, однако я собираюсь отметьте это как можно скорее.