str.Template 4 times slower than calling replace multiple times

J

Jack Steven

Isn't string.Template suppose to be faster than calling replace multiple
times? That's what I thought until I benchmarked this code, where
string.Template ended up being 4 times slower.

This doesn't make sense to me, since unlike when you are calling replace
multiple times, code behind Template can scan the string only once, and it
doesn't have to allocate multiple strings. So why is slower? Is there a way
to improve it's speed?


from string import Template
from time import time

def test1(format, user, channel, message):
nick, id, host = user
s = format
s = s.replace('$nick', nick)
s = s.replace('$id', id)
s = s.replace('$host', host)
s = s.replace('$channel', channel)
s = s.replace('$message', message)

def test2(format, user, channel, message):
nick, id, host = user
s = Template(format)
d = {
'nick': nick,
'id': id,
'host': host,
'channel': channel,
'message': message,
}
s = s.substitute(d)

user = ('jacks-', 'id', '127.0.0.1')
channel = '#test'
message = 'this is a message'
format = '<$nick@$host> $message'

for test in (test1, test2):
start = time()
for i in xrange(100000):
test(format, user, channel, message)
end = time()
print 'Done in %f seconds' % (end - start)
 
J

John Machin

Isn't string.Template suppose to be faster than calling replace multiple
times? That's what I thought until I benchmarked this code, where
string.Template ended up being 4 times slower.

This doesn't make sense to me, since unlike when you are calling replace
multiple times, code behind Template can scan the string only once, and it
doesn't have to allocate multiple strings. So why is slower? Is there a way
to improve it's speed?

from string import Template
from time import time

def test1(format, user, channel, message):
    nick, id, host = user
    s = format
    s = s.replace('$nick', nick)
    s = s.replace('$id', id)
    s = s.replace('$host', host)
    s = s.replace('$channel', channel)
    s = s.replace('$message', message)

def test2(format, user, channel, message):
    nick, id, host = user
    s = Template(format)
    d = {
        'nick': nick,
        'id': id,
        'host': host,
        'channel': channel,
        'message': message,
    }
    s = s.substitute(d)

user    = ('jacks-', 'id', '127.0.0.1')
channel = '#test'
message = 'this is a message'
format  = '<$nick@$host> $message'

for test in (test1, test2):
    start = time()
    for i in xrange(100000):
        test(format, user, channel, message)
    end = time()
    print 'Done in %f seconds' % (end - start)

A couple of points:
(a) string.Template is written in Python, not C so (1) it runs slower
(2) you can get some of your answer from the source on your computer
(b) It has to be smarter than shotgun replaces ... You may know that
your template contains "$nick" and not "$nick $nickname $nickers" but
it doesn't.
 
C

Chris Rebert

A couple of points:
(a) string.Template is written in Python, not C so (1) it runs slower
(2) you can get some of your answer from the source on your computer
(b) It has to be smarter than shotgun replaces ... You may know that
your template contains "$nick" and not "$nick $nickname $nickers" but
it doesn't.

IOW, the comparison being made is fatally flawed, hence the
unfavorable but incorrect results.

Cheers,
Chris
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,904
Latest member
HealthyVisionsCBDPrice

Latest Threads

Top