Если вы используете интерпретируемый Python 2.7.6 и пытаетесь прочитать около 50 миллионов целых чисел (подписанных, 32 бита) из файла, связанного с stdin, то что самое быстрое (производительность) способ сделать это, если они входят в одну строку (нет \ n в конце), пространство разделены ?, или, возможно, разделены запятой? Предпочтительно использовать генераторы и/или считывать фрагменты, чтобы весь файл не был сразу прочитан в памяти или список всех 50M целых чисел, сохраненных сразу. Список должен быть сведен к сумме всех смежных элементов xors (A[0]^A[1] + A[1]^A[2] + ...)
, числа очень близки друг к другу, поэтому сокращение не прерывает 32 бита целое число со знаком.Оптимизация производительности IO - чтение 50 миллионов целых чисел, разделенных пробелами
Исходная строка может быть добавлена либо к числу целых чисел (n), либо к длине строки (L).
Я не владею питоном, и получаю недопустимые результаты (> 30 секунд). На десятую часть ограничений я делаю около 6 секунд, поэтому чувствую, что мне нужно улучшить это намного больше.
Мне кажется, что если бы они были отделены друг от друга, это могло бы быть возможно. Есть ли способ сказать python использовать другой разделитель для readline()?
Пробовал:
for ch in stdin.read()
, это занимает 3 секунды в цикле все ч, а строить целые числа с умножений, а затем делает сокращение вручную занимает слишком много времени.read(n)
, считывая фрагменты, а затем сохраняя неполный хвост для последующего использования, используя split и map int, для xrange и уменьшаем на куске последовательно, чтобы создать список сокращений, но снова, похоже, занять слишком много времени.
Я сделал это на более быстрых языках уже благодаря поиску интерпретируемых ответов python.
Это мой лучший код, который длится через 18 секунд в некоторых случаях, в других - слишком медленно. Но это быстрее, чем версия, где я построил целые числа с умножениями на аккумуляторе. Это также быстрее, чем чтение байта на байт: read(1)
.
def main():
n,l=map(int,raw_input().split())
#print n
#print l
r = 0 #result
p = 0 #previous
q = 0 #current
b = [] #buffer
for c in sys.stdin.read(): #character
if c == ' ':
q = int(''.join(b))
b = []
r += q^p #yes there is a bug with A[0] but lets optimize the loop for now
p = q
else:
b.append(c)
r += int(''.join(b))^p
print r
main()
я могу видеть, что это может (возможно) можно улучшить, если это было возможно инициализировать б только один раз, а затем не используя добавления, но на самом деле доступ к индексу, но когда я попытался b = [None]*12
я получил RTE во время присоединиться к cant join None
, нужно присоединиться к диапазону, поэтому я бросил идею на данный момент. Также более быстрые функции выполняют то, что я уже делаю.
Update:
import re
import sys
from collections import deque
def main():
n,l=map(int,raw_input().split())
#print n
#print l
r = 0
p = 0
q = 0
b = sys.stdin.read(l)
b = deque(b.rsplit(' ',4000000))
n = len(b)
while n == 4000001:
c = b.popleft()
b = map(int,b)
for i in xrange(n-2,0,-1):
r += b[i]^b[i-1]
m = b[0]
b = deque(c.rsplit(' ',3999999))
b.append(m)
n = len(b)
b = map(int,b)
for i in xrange(n-1,0,-1):
r += b[i]^b[i-1]
print r
main()
Это в 3 раза быстрее (10000000 может быть сделано в течение 6 секунд, но 50 принимают более 30), за 50 миллионов, это все еще слишком медленно, IO, кажется, не основное узкое место, но обработка данных.
Вместо deque можно использовать обычный список, вызывая pop (0) вместо popleft. Также можно не называть len (b) на каждом цикле, поскольку у вас есть n в начале и может вычесть вместо этого, но, кроме того, это кажется самым быстрым до сих пор.
Это не похоже на вопрос, связанный с [csv], так как вы говорите, что числа разделены пробелами. Можете ли вы показать нам код, который вы пробовали до сих пор - возможно, самая быстрая версия? –
вопрос говорит, что он может быть разделен запятой (если было что-то, что обрабатывает запятые, а не пробелы, что я сомневаюсь) – gia
Если файл был в двоичном формате, вы можете использовать 'array.fromfile', который должен быть довольно быстрым. https://docs.python.org/3/library/array.html#array.array.fromfile У вас есть контроль над тем, как файл был написан? –