Μιχάλη, αυτά που είχα γράψει ήταν περισσότερο σχετικά με αυτά που είχε γράψει ο myle.
Σε σχέση με αυτό που ρωτάς, δες το παρακάτω. Ελπίζω να σε βοηθήσει.
#! /usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import division
import cProfile
BIG_NUMBER = 1000000
def conc1(s, l):
for i in range(int(BIG_NUMBER / 100)):
s = s + l + '\n'
return s
def conc2(s, l):
l = l + "\n"
for i in range(BIG_NUMBER):
s = s + l
return s
def conc3(s, l):
l = l + "\n"
for i in range(BIG_NUMBER):
s += l
return s
def conc4(s, l):
for i in range(BIG_NUMBER):
s += l + '\n'
return s
def conc5(s, l):
for i in range(BIG_NUMBER):
s = s + (l + '\n')
return s
def str_join(l):
l += "n"
l = [l for i in range(BIG_NUMBER)]
l = "".join(l)
return l
s = ''
l = '00000000000000000000000000000000000000000000000000000000000000000000000000000000'
cProfile.run("conc1(s, l)")
cProfile.run("conc2(s, l)")
cProfile.run("conc3(s, l)")
cProfile.run("conc4(s, l)")
cProfile.run("conc5(s, l)")
cProfile.run("str_join(l)")
Η conc1 είναι η πιο αργή version από όλες και με μεγάλη διαφορά. Ο λόγος είναι ότι μέσα στο for-loop δημιουργείται ξανά και ξανά ένα καινούριο string.
Η conc2 και η conc3 έχουν την ίδια απόδοση. Και στις δύο δημιουργούμε έξω από το for-loop το string που θέλουμε να κάνουμε concatenate. Εικάζω ότι εσωτερικά, το bytecode που θα δημιουργεί η Python θα είναι το ίδιο για "s += l" και "s = s + l", για αυτό και οι κοινοί χρόνοι.
Η conc4 και η conc5 έχουν και αυτές ουσιαστικά την ίδια απόδοση μεταξύ τους αλλά χειρότερη από της conc2 και conc3. Ο λόγος είναι ότι δημιουργείται εντός του loop ένα νέο string (το 'l + "\n"'). Στη συνέχεια ο κώδικας είναι αντίστοιχος με αυτόν των conc2 και conc3 (βοηθούνε οι παρενθέσεις σε αυτό).
Η str_join είναι ο βέλτιστος τρόπος νομίζω για να κάνεις το string concatenation, αν και ίσως δεν είναι τόσο ευανάγνωστος όσο οι υπόλοιποι.
Τρέχοντας τον παραπάνω κώδικα σε Python3, ο χρόνος της conc1 5πλασιάζεται, ενώ όλων των υπολοίπων περίπου διπλασιάζεται σε σχέση με την Python2.
Όπως φάνηκε από το προηγούμενο post μου, η ταχύτητα με την οποία γίνεται το string concatenation είναι σχεδόν η ίδια τόσο στην Python2 όσο και στην Python3.
Εκεί που εμφανίζεται η διαφορά τους είναι στον χρόνο που θέλουν τα loops για να τρέξουν. Εκεί η Python2 πρέπει να είναι αρκετά πιο γρήγορη από την Python3.
Πέρα από την ταχύτητα εκτέλεσης του for-loop, σημασία έχει και ο τρόπος με τον οποίο δομείται η έκφραση που βρίσκεται εντός του loop. Ουσιαστικά αν δημιουργείς καινούρια strings τότε ο κώδικας σου είναι αργός. Αν οι αλλαγές γίνονται in place, τότε ο κώδικας τρέχει πιο γρήγορα (αυτό που είπε ο myle δηλαδή).
Για διαφορετικές εργασίες από το string concatenation, λένε ότι είναι δυνατόν να πετύχεις ακόμη καλύτερη απόδοση, χρησιμοποιώντας εργαλεία όπως οι built-in συναρτήσεις "map", "reduce", "filter" οι οποίες έχουν υλοποιηθεί σε C, αποφεύγοντας με τον τρόπο αυτό κάποιο for-loop. Δεν έχω προσωπική εμπειρία για τις διαφορές στην απόδοση.
Δε ξέρω αν σε βοήθησα,
Παναγιώτης