2016-10-07 2 views
0

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

Мой код:

import sys 

MAX_BUFFER_SIZE = 4 * (1024 ** 3) 

class MyBuffer(object): 
    b = "" 

    def append(self, s): 
     if sys.getsizeof(self.b) > MAX_BUFFER_SIZE: 
      #...print to file... empty buffer 
      self.b = "" 
     else: 
      self.b += s 


buffer = MyBuffer() 
for s in some_text: 
    buffer.append(s) 

Однако это сравнение (sys.getsizeof(self.buffer) > MAX_BUFFER_SIZE) является слишком медленным (т.е. без сравнения, в целом выполнение занимает менее 1 секунды, с сопоставлением он принимает как 5 минут.).

На данный момент я могу вместить все some_string в память, и поэтому буфер фактически никогда не становится больше MAX_BUFFER_SIZE, но я должен убедиться, что мой код работает для огромных файлов (несколько TBs в размере) тоже.

Edit:

Этот код выполняется в пункте 1 секунду:

import sys 

buffer = "" 
for s in some_text: 
    buffer += s 

#print out to file 

Проблема заключается в том, что буфер может стать слишком большим.

Кроме того, этот код также работает под 1 секунду:

import sys 

MAX_BUFFER_SIZE = 4 * (1024 ** 3) 

class MyBuffer(object): 
    b = "" 

    def append(self, s): 
     print sys.getsizeof(self.b) 


buffer = MyBuffer() 
for s in some_text: 
    buffer.append(s) 

EDIT 2:

К сожалению, медленная часть на самом деле добавление в буфер, а не само по себе сравнение, как я думал. Когда я тестировал код, я прокомментировал всю инструкцию if/else вместо первой части.

Следовательно, существует эффективный способ хранения буфера?

+1

я предлагаю использовать 'LEN (self.b)' вместо 'sys.getsizeof (self.b)'. 'self.b' - простая строка, поэтому получение ее размера тривиально и быстро. Обратите внимание, однако, что постоянное добавление к строке выполняется медленно, так как часто требуется перераспределить память для строки и перераспределение 4 ГБ займет некоторое время. –

+0

Когда я изменяю buffer.append (s) только на 'my_global_buffer + = s', а затем распечатываю файл в самом конце, выполнение все равно меньше 1 секунды, поэтому я не думаю, что добавление к самому буфере это медленная часть. – emihir0

+0

@ emihir0 В некоторых случаях CPython может оптимизировать добавление буфера, и немного сложно понять, возможно ли это в вашем случае. Это зависит от количества ссылок на строку, которую вы добавляете, и, возможно, от некоторых других факторов. –

ответ

1

Undeleting и редактирование моего ответа на основе изменений на вопрос.

Неверно предположить, что сравнение происходит медленно. На самом деле сравнение происходит быстро. Действительно, очень быстро.

Почему вы не избегаете изобретать колесо с помощью буферизованного ввода-вывода?

Необязательный аргумент буферизации указывает размер буфера для файла: 0 означает небуферизованный, 1 означает буферизацию строки, любое другое положительное значение означает использование буфера (приблизительно) этого размера (в байтах). Отрицательная буферизация означает использование системы по умолчанию, которая обычно буферизируется для tty-устройств и полностью буферизируется для других файлов. Если этот параметр опущен, используется системная настройка по умолчанию. [2]

https://docs.python.org/2/library/functions.html#open

+0

Я не могу следовать. Почему скорость 'sys.getsizeof()' зависит от размера строки? –

+0

@ e4c5, когда я просто печатаю sys.getsizeof (self.b) и комментирую остальную часть метода, он все еще работает менее чем за 1 секунду, поэтому я бы подумал, что получение размера буфера не является дорогостоящей частью, это сравнение. – emihir0

+0

Я сделал неправильный вывод @SvenMarnach – e4c5