Esta é uma duplicata do equivalente em Python de Java StringBuffer . CUIDADO: As respostas aqui estão muito desatualizadas e, na verdade, tornaram-se enganosas. Veja essa outra pergunta para respostas que são mais relevantes para as versões modernas do Python (certamente 2.7 e acima).
Construir strings longas na linguagem de programação Python às vezes pode resultar em um código de execução muito lento. Neste artigo, investigo o desempenho computacional de vários métodos de concatenação de strings.
Observe que este artigo foi escrito com base no Python 2.2. Os testes provavelmente seriam um pouco diferentes em uma versão moderna do Python (o CPython geralmente otimiza com sucesso a concatenação, mas você não quer depender disso em códigos importantes) e uma expressão geradora onde ele usa uma compreensão de lista seria digna de consideração .
Mike Graham
4
Seria bom trazer alguns destaques nesse artigo, pelo menos algumas das implementações (para evitar problemas de podridão de link).
jpmc26
3
Método 1: resultString + = appendString é o mais rápido de acordo com os testes de @ Antoine-tran abaixo
Justas
5
Sua citação não responde de forma alguma à pergunta. Inclua as partes relevantes em sua própria resposta, para cumprir as novas diretrizes.
Processo de Fundo Monica em
27
Usei o código de Oliver Crow (link fornecido por Andrew Hare) e adaptei-o um pouco para ajustar o Python 2.7.3. (usando o pacote timeit). Eu executei em meu computador pessoal, Lenovo T61, 6GB de RAM, Debian GNU / Linux 6.0.6 (squeeze).
Aqui está o resultado para 10.000 iterações:
método1: 0,0538418292999 s
tamanho do processo 4800 kb
método 2: 0,22602891922 s
tamanho do processo 4960 kb
método 3: 0,0605459213257 s
tamanho do processo 4980 kb
método 4: 0,0544030666351 s
tamanho do processo 5536 kb
método 5: 0,0551080703735 s
tamanho do processo 5272 kb
método 6: 0,0542731285095 s
tamanho do processo 5512 kb
e para 5.000.000 de iterações (o método 2 foi ignorado porque foi executado muito lentamente, como para sempre):
método 1: 5,88603997231 s
tamanho do processo 37976 kb
método 3: 8,40748500824 s
tamanho do processo 38024 kb
método 4: 7,96380496025 segs
tamanho do processo 321968 kb
método 5: 8,03666186333 s
tamanho do processo 71720 kb
método 6: 6,68192911148 s
tamanho do processo 38240 kb
É bastante óbvio que os caras do Python fizeram um ótimo trabalho para otimizar a concatenação de strings e, como Hoare disse: "a otimização prematura é a raiz de todos os males" :-)
Não é uma otimização prematura evitar otimizações frágeis e dependentes do interpretador. Se você quiser portar para PyPy ou correr o risco de encontrar um dos muitos casos de falha sutis para a otimização, faça as coisas da maneira certa.
Veedrac
1
Parece que o Método 1 é mais fácil para o compilador otimizar.
mbomb007
25
Depender de otimizações do compilador é frágil. Os benchmarks vinculados na resposta aceita e os números fornecidos pela Antoine-tran não são confiáveis. Andrew Hare comete o erro de incluir uma chamada para reprem seus métodos. Isso retarda todos os métodos igualmente, mas obscurece a verdadeira penalidade na construção da string.
Use join. É muito rápido e mais robusto.
$ ipython3
Python3.5.1(default,Mar22016,03:38:02)IPython4.1.2--An enhanced InteractivePython.In[1]: values =[str(num)for num in range(int(1e3))]In[2]:%%timeit
...:''.join(values)...:100000 loops, best of 3:7.37µs per loop
In[3]:%%timeit
...: result =''...:for value in values:...: result += value
...:10000 loops, best of 3:82.8µs per loop
In[4]:import io
In[5]:%%timeit
...: writer = io.StringIO()...:for value in values:...: writer.write(value)...: writer.getvalue()...:10000 loops, best of 3:81.8µs per loop
Sim, a reprchamada domina o tempo de execução, mas não há necessidade de tornar o erro pessoal.
Alex Reinking de
3
@AlexReinking, desculpe, nada de pessoal significava. Não sei o que o fez pensar que era pessoal. Mas se fosse o uso de seus nomes, usei-os apenas para me referir às respostas do usuário (corresponde a nomes de usuários, não tenho certeza se existe uma maneira melhor).
GrantJ
1
exemplo de bom tempo que separa as operações de inicialização e concatenação de dados
aiodintsov
19
Python tem várias coisas que atendem a propósitos semelhantes:
Uma maneira comum de construir cordas grandes a partir de pedaços é aumentar uma lista de cordas e juntá-la quando terminar. Este é um idioma Python usado com freqüência.
Para construir strings que incorporam dados com formatação, você faria a formatação separadamente.
Para inserção e exclusão em um nível de caractere, você manteria uma lista de strings de comprimento um. (Para fazer isso a partir de uma string, você chamaria list(your_string). Você também pode usar um UserString.MutableStringpara isso.
(c)StringIO.StringIO é útil para coisas que de outra forma levariam um arquivo, mas nem tanto para a construção geral de strings.
Não há analogia explícita - acho que se espera que você use concatenações de string (provavelmente otimizadas como dito antes) ou classe de terceiros (duvido que sejam muito mais eficientes - as listas em python são de tipo dinâmico, então não funciona rápido char [] para buffer como eu suponho). Classes semelhantes a Stringbuilder não são otimização prematura por causa do recurso inato de strings em muitas linguagens (imutabilidade) - que permite muitas otimizações (por exemplo, referenciar o mesmo buffer para fatias / substrings). Stringbuilder / stringbuffer / classes semelhantes a stringstream funcionam muito mais rápido do que a concatenação de strings (produzindo muitos pequenos objetos temporários que ainda precisam de alocações e coleta de lixo) e até mesmo ferramentas de formatação de string do tipo printf, sem a necessidade de interpretar a sobrecarga do padrão de formatação que é muito demorada para muitas chamadas de formato.
Caso você esteja procurando um método rápido de concatenação de strings em Python, não precisa de uma classe StringBuilder especial. A concatenação simples funciona tão bem sem a penalidade de desempenho vista em C #.
Respostas:
Não há correlação um a um. Para um artigo realmente bom, consulte Concatenação eficiente de strings em Python :
fonte
Usei o código de Oliver Crow (link fornecido por Andrew Hare) e adaptei-o um pouco para ajustar o Python 2.7.3. (usando o pacote timeit). Eu executei em meu computador pessoal, Lenovo T61, 6GB de RAM, Debian GNU / Linux 6.0.6 (squeeze).
Aqui está o resultado para 10.000 iterações:
e para 5.000.000 de iterações (o método 2 foi ignorado porque foi executado muito lentamente, como para sempre):
É bastante óbvio que os caras do Python fizeram um ótimo trabalho para otimizar a concatenação de strings e, como Hoare disse: "a otimização prematura é a raiz de todos os males" :-)
fonte
Depender de otimizações do compilador é frágil. Os benchmarks vinculados na resposta aceita e os números fornecidos pela Antoine-tran não são confiáveis. Andrew Hare comete o erro de incluir uma chamada para
repr
em seus métodos. Isso retarda todos os métodos igualmente, mas obscurece a verdadeira penalidade na construção da string.Use
join
. É muito rápido e mais robusto.fonte
repr
chamada domina o tempo de execução, mas não há necessidade de tornar o erro pessoal.Python tem várias coisas que atendem a propósitos semelhantes:
list(your_string)
. Você também pode usar umUserString.MutableString
para isso.(c)StringIO.StringIO
é útil para coisas que de outra forma levariam um arquivo, mas nem tanto para a construção geral de strings.fonte
Usando o método 5 acima (O Pseudo Arquivo), podemos obter um desempenho e flexibilidade muito bons
agora usando
fonte
você pode tentar StringIO ou cStringIO
fonte
Não há analogia explícita - acho que se espera que você use concatenações de string (provavelmente otimizadas como dito antes) ou classe de terceiros (duvido que sejam muito mais eficientes - as listas em python são de tipo dinâmico, então não funciona rápido char [] para buffer como eu suponho). Classes semelhantes a Stringbuilder não são otimização prematura por causa do recurso inato de strings em muitas linguagens (imutabilidade) - que permite muitas otimizações (por exemplo, referenciar o mesmo buffer para fatias / substrings). Stringbuilder / stringbuffer / classes semelhantes a stringstream funcionam muito mais rápido do que a concatenação de strings (produzindo muitos pequenos objetos temporários que ainda precisam de alocações e coleta de lixo) e até mesmo ferramentas de formatação de string do tipo printf, sem a necessidade de interpretar a sobrecarga do padrão de formatação que é muito demorada para muitas chamadas de formato.
fonte
Caso você esteja procurando um método rápido de concatenação de strings em Python, não precisa de uma classe StringBuilder especial. A concatenação simples funciona tão bem sem a penalidade de desempenho vista em C #.
Veja a resposta de Antoine-tran para resultados de desempenho
fonte