'"%s/" % var' preferred to 'var + "/"'?

56 views
Skip to first unread message

Joost Cassee

unread,
Aug 21, 2008, 11:41:49 AM8/21/08
to Django developers
Hi all,

Just a quick question to set my head right for future Django
contributions. Why is "%s/" % var better than var + '/'? I can think
of some reasons: 1) consistency with other code, 2) certainty of
string concatenation. But is the second expression not much faster?
(This is an honest question, no criticism or anything.)

Regards,

Joost

Jeff Anderson

unread,
Aug 21, 2008, 12:00:00 PM8/21/08
to django-d...@googlegroups.com
I'm not sure about speed in this type of trivial case, but I remembered
reading about formatting vs. concatenation in Dive into Python[1].
Basically the advantages/disadvantages are as follows:

* concatenation works only with strings and strings. You can't do:

>>> "Hello. The number of apples I have is: " + 12

But you can do:

>>> "Hello. The number of apples I have is: %d" % (12,)

If all you are doing is a simple concatenation, I don't see any reason
to really worry about the speed, unless you are trying to do megabytes
of string concatenation.

If you use string formatting in other places in your code, yes using it
for simple concatenations would probably enhance consistency of coding
style, but I wouldn't consider it wrong to throw in a concatenation
operator.

You got me curious so I wrote a simple loop to concatenate a very small
string a million times. I ran it using both methods.

jefferya@pax:~$ time python concattest.py

real 0m0.557s
user 0m0.530s
sys 0m0.022s
jefferya@pax:~$ time python concattest2.py

real 0m0.834s
user 0m0.803s
sys 0m0.024s

concattest.py uses the concatenation operator.
concattest2.py uses string formatting.

I would conclude that for the sake of optimization, it is better to use
the concatenation operator for simple cases. I haven't done further
testing to see if string formatting ever performs better in certain
situations, but for the very simple test case I used, string formatting
appears to be slower.

Hopefully this answers your question!

Jeff Anderson

concattest.py:
s1 = "Hello"
i=0
while i<999000:
greeting="English: " + s1
i=i+1

concattest2.py:
s1 = "Hello"
i=0
while i<999000:
greeting="English: %s" % (s1,)
i=i+1

[1] http://diveintopython.org/native_data_types/formatting_strings.html

signature.asc

Waylan Limberg

unread,
Aug 21, 2008, 12:00:44 PM8/21/08
to django-d...@googlegroups.com
Well, according to the python beginners book; "Dive Into Python" [1],
string formatting is less error prone as it also does type coercion
whereas string concatenation only works when all objects are already
strings. When it's possible that a user will be passing in parts of
the concatenation, I'd rather be using formatting for that reason
alone.

I had thought that I read from that same source that formatting is
faster than concatenation (and that's why I checked there before
responding), but I don't see that mentioned. Not sure where I got that
idea or if its even true.

[1]: http://diveintopython.org/native_data_types/formatting_strings.html

--
----
Waylan Limberg
way...@gmail.com

Message has been deleted

Ian Kelly

unread,
Aug 21, 2008, 12:22:16 PM8/21/08
to django-d...@googlegroups.com
On Thu, Aug 21, 2008 at 10:00 AM, Waylan Limberg <way...@gmail.com> wrote:
> I had thought that I read from that same source that formatting is
> faster than concatenation (and that's why I checked there before
> responding), but I don't see that mentioned. Not sure where I got that
> idea or if its even true.

Formatting is faster than serial concatenation, which often results in
copying the same substring multiple times. A single concatenation is
usually faster than formatting, however.

Yuri Baburov

unread,
Aug 21, 2008, 2:16:08 PM8/21/08
to django-d...@googlegroups.com
Also you are able to use %s for numbers and any custom types: "str%s"
% 12 but not "str" + 12.
Less errors -- more fun.

--
Best regards, Yuri V. Baburov, ICQ# 99934676, Skype: yuri.baburov,
MSN: bu...@live.com

Waylan Limberg

unread,
Aug 21, 2008, 2:58:38 PM8/21/08
to django-d...@googlegroups.com

PEP 8 has something to say about this under "Programming Recommendations":

- Code should be written in a way that does not disadvantage other
implementations of Python (PyPy, Jython, IronPython, Pyrex, Psyco,
and such).

For example, do not rely on CPython's efficient implementation of
in-place string concatenation for statements in the form a+=b or a=a+b.
Those statements run more slowly in Jython. In performance sensitive
parts of the library, the ''.join() form should be used instead. This
will ensure that concatenation occurs in linear time across various
implementations.

Of course, this doesn't say anything about formatting - just joins,
but concatenation seems to be generally discouraged wherever we look.

Ronny Haryanto

unread,
Aug 22, 2008, 12:28:35 AM8/22/08
to django-d...@googlegroups.com

lingrlongr

unread,
Aug 22, 2008, 12:42:54 AM8/22/08
to Django developers
You can also map a dictionary of values to the format string:

>>> num = 99
>>> obj = 'red balloons'
>>> print '%(a)d %(b)s' % {'a': num, 'b': obj}
99 red baloons

Keith

On Aug 22, 12:28 am, "Ronny Haryanto" <ro...@haryan.to> wrote:
> On Thu, Aug 21, 2008 at 10:41 PM, Joost Cassee <jo...@cassee.net> wrote:
> > Just a quick question to set my head right for future Django
> > contributions. Why is "%s/" % var better than var + '/'? I can think
> > of some reasons: 1) consistency with other code, 2) certainty of
> > string concatenation. But is the second expression not much faster?
> > (This is an honest question, no criticism or anything.)
>
> It's also discussed in Recipe 3.5, "Combining Strings", in the Python Cookbook:
>
> http://books.google.com/books?id=yhfdQgq8JF4C&pg=PA73&lpg=PA73&dq=pyt...
>
> Ronny

Joost Cassee

unread,
Aug 22, 2008, 4:49:51 AM8/22/08
to Django developers
Thanks for all the great info. Usually articles refer ''.join(...) as
the fastest concat operation, but it won't do type coersion of course.
I was interested whether there was a Django standard for this sort of
thing. In any case the '+' operator is discouraged by all.

Regards,

Joost

phillc

unread,
Aug 23, 2008, 11:36:06 PM8/23/08
to Django developers
a python string is immutable
using the + operation on it causes strings to be copied into memory
and made into another immutable string... which doesn;t save much...
but the next uses of + requires another copy, and the next so on...
where as using % does copy once

Fredrik Lundh

unread,
Aug 24, 2008, 1:54:05 PM8/24/08
to django-d...@googlegroups.com
Joost Cassee wrote:

that's outdated information -- recent Python versions (2.4 and later)
can do "+" and "+=" in place in many cases. join is still preferred if
you have lots of string fragments, but using it for 2-3 pieces is
usually pointless.

</F>

Reply all
Reply to author
Forward
0 new messages