Подтвердить что ты не робот

Когда используется StringIO?

Использование StringIO в качестве строкового буфера медленнее, чем использование списка в качестве буфера.

Когда используется StringIO?

from io import StringIO


def meth1(string):
    a = []
    for i in range(100):
        a.append(string)
    return ''.join(a)

def meth2(string):
    a = StringIO()
    for i in range(100):
        a.write(string)
    return a.getvalue()


if __name__ == '__main__':
    from timeit import Timer
    string = "This is test string"
    print(Timer("meth1(string)", "from __main__ import meth1, string").timeit())
    print(Timer("meth2(string)", "from __main__ import meth2, string").timeit())

Результаты:

16.7872819901
18.7160351276
4b9b3361

Ответ 1

Если вы измеряете скорость, вы должны использовать cStringIO.

Из docs:

Модуль cStringIO предоставляет интерфейс, аналогичный интерфейсу Модуль StringIO. Тяжелое использование Объекты StringIO.StringIO могут быть созданы более эффективно с помощью функции StringIO() из этого модуля.

Но точка StringIO должна быть файлоподобным объектом, потому что когда что-то ожидает, и вы не хотите использовать фактические файлы.

Изменить: Я заметил, что вы используете from io import StringIO, поэтому вы, вероятно, находитесь на Python >= 3 или не менее 2.6. Отдельные StringIO и cStringIO ушли в Py3. Не знаю, какую реализацию они использовали для обеспечения io.StringIO. Существует также io.BytesIO.

Ответ 2

Основное преимущество StringIO заключается в том, что его можно использовать там, где ожидался файл. Так вы можете сделать, например:

import sys
import StringIO

out = StringIO.StringIO()

sys.stdout = out

print "hi, I'm going out"

sys.stdout = sys.__stdout__

print out.getvalue()

Ответ 3

Ну, я не знаю, хочу ли я назвать это, используя его как "буфер", вы просто умножаете строку на 100 раз двумя сложными способами. Вот простой способ:

def meth3(string):
    return string * 100

Если мы добавим это к вашему тесту:

if __name__ == '__main__':

    from timeit import Timer
    string = "This is test string"
    # Make sure it all does the same:
    assert(meth1(string) == meth3(string))
    assert(meth2(string) == meth3(string))
    print(Timer("meth1(string)", "from __main__ import meth1, string").timeit())
    print(Timer("meth2(string)", "from __main__ import meth2, string").timeit())
    print(Timer("meth3(string)", "from __main__ import meth3, string").timeit())

Он оказался быстрее в качестве бонуса:

21.0300650597
22.4869811535
0.811429977417

Если вы хотите создать связку строк, а затем присоедините их, метод meth1() будет правильным. Нет смысла записывать его в StringIO, что совершенно другое, а именно строка с файловым интерфейсом потока.