FAQ
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)

Search Discussions

  • John Machin at Mar 9, 2009 at 5:23 am

    On Mar 9, 3:15?pm, Jack Steven wrote:
    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.
  • Chris Rebert at Mar 9, 2009 at 5:38 am

    On Sun, Mar 8, 2009 at 10:23 PM, John Machin wrote:
    On Mar 9, 3:15?pm, Jack Steven wrote:
    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.
    IOW, the comparison being made is fatally flawed, hence the
    unfavorable but incorrect results.

    Cheers,
    Chris

    --
    I have a blog:
    http://blog.rebertia.com

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
grouppython-list @
categoriespython
postedMar 9, '09 at 4:15a
activeMar 9, '09 at 5:38a
posts3
users3
websitepython.org

People

Translate

site design / logo © 2022 Grokbase