Чтение Очень Большого Текстового Файла Одной Строки

у меня 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 секунды, намного медленнее, но, по крайней мере, он дал мне целое значение.

спасибо всем за ваши бесценные ответы, однако я собираюсь отметьте это как можно скорее.