Format Strings VS Concatenation

Format strings vs concatenation

It's just for the looks. You can see at one glance what the format is. Many of us like readability better than micro-optimization.

Let's see what IPython's %timeit says:

Python 3.7.2 (default, Jan  3 2019, 02:55:40)
IPython 5.8.0
Intel(R) Core(TM) i5-4590T CPU @ 2.00GHz

In [1]: %timeit root = "sample"; output = "output"; path = "{}/{}".format(root, output)
The slowest run took 12.44 times longer than the fastest. This could mean that an intermediate result is being cached.
1000000 loops, best of 5: 223 ns per loop

In [2]: %timeit root = "sample"; output = "output"; path = root + '/' + output
The slowest run took 13.82 times longer than the fastest. This could mean that an intermediate result is being cached.
10000000 loops, best of 5: 101 ns per loop

In [3]: %timeit root = "sample"; output = "output"; path = "%s/%s" % (root, output)
The slowest run took 27.97 times longer than the fastest. This could mean that an intermediate result is being cached.
10000000 loops, best of 5: 155 ns per loop

In [4]: %timeit root = "sample"; output = "output"; path = f"{root}/{output}"
The slowest run took 19.52 times longer than the fastest. This could mean that an intermediate result is being cached.
10000000 loops, best of 5: 77.8 ns per loop

String.format() vs + operator

If you are looking for performance only I believe that using StringBuilder/StringBuffer is the most efficient way to build strings. Even if the Java compiler is smart enough to translate most of String concatenations to StringBuilder equivalent.

If you are looking for readability the String.format thing is the much clearer I think, and this is what I use also unless I need to rely on high performance.

So if your main concern is not performance, meaning this code is not in a path that is called a lot, you may prefer to use String.format as it gives a better idea of the resulting String (like you said).

Besides, using String.format lets you use the format thing, which means you can use it for padding Strings, formatting numbers, dates, and so on, which would make the code even worse if using simple concatenation.

Edit for Chuu:

Using JAD, you can see that the following code:

public class Test {
public static void main(String[] args) {
String str = "a" + "b" + "c";
String str2 = "foo" + str + "bar" + str;
System.out.println(str2);
}
}

when decompiled will look like:

public class Test {
public static void main(String[] args) {
String str = "abc";
String str2 = new StringBuilder("foo").append(str).append("bar").append(str).toString();
System.out.println(str2);
}
}

Proof of that can also be found using the javap utility that will show you the Java bytecode under a .class file:

public static void main(java.lang.String[] args);
0 ldc <String "abc"> [16]
2 astore_1 [str]
3 new java.lang.StringBuilder [18]
6 dup
7 ldc <String "foo"> [20]
9 invokespecial java.lang.StringBuilder(java.lang.String) [22]
12 aload_1 [str]
13 invokevirtual java.lang.StringBuilder.append(java.lang.String) : java.lang.StringBuilder [25]
16 ldc <String "bar"> [29]
18 invokevirtual java.lang.StringBuilder.append(java.lang.String) : java.lang.StringBuilder [25]
21 aload_1 [str]
22 invokevirtual java.lang.StringBuilder.append(java.lang.String) : java.lang.StringBuilder [25]
25 invokevirtual java.lang.StringBuilder.toString() : java.lang.String [31]
28 astore_2 [str2]
29 getstatic java.lang.System.out : java.io.PrintStream [35]
32 aload_2 [str2]
33 invokevirtual java.io.PrintStream.println(java.lang.String) : void [41]
36 return

Python string formatting: % vs concatenation

This could easily become an opinion-based thread, but I find formatting to be more readable in most cases, and more maintainable. It's easier to visualize what the final string will look like, without doing "mental concatenation". Which of these is more readable, for example?

errorString = "Exception occurred ({}) while executing '{}': {}".format(
e.__class__.__name__, task.name, str(e)
)

Or:

errorString = "Exception occurred (" + e.__class__.__name__
+ ") while executing '" + task.name + "': " + str(e)

As for whether to use % or .format(), I can answer more objectively: Use .format(). % is the "old-style", and, per the Python Documentation they may soon be removed:

Since str.format() is quite new, a lot of Python code still uses the % operator. However, because this old style of formatting will eventually be removed from the language, str.format() should generally be used.

Later versions of the documentation have stopped mentioning this, but nonetheless, .format() is the way of the future; use it!

Concatenation is faster, but that should not be a concern. Make your code readable and maintainable as a first-line goal, and then optimize the parts you need to optimize later. Premature optimization is the root of all evil ;)

Is it better practice to use String.format over string Concatenation in Java?

I'd suggest that it is better practice to use String.format(). The main reason is that String.format() can be more easily localised with text loaded from resource files whereas concatenation can't be localised without producing a new executable with different code for each language.

If you plan on your app being localisable you should also get into the habit of specifying argument positions for your format tokens as well:

"Hello %1$s the time is %2$t"

This can then be localised and have the name and time tokens swapped without requiring a recompile of the executable to account for the different ordering. With argument positions you can also re-use the same argument without passing it into the function twice:

String.format("Hello %1$s, your name is %1$s and the time is %2$t", name, time)

Built-in string formatting vs string concatenation as logging parameter

I believe you have your answer there.

Concatenation is calculated beforehand the condition check. So if you call your logging framework 10K times conditionally and all of them evaluates to false, you will be concatenating 10K times with no reason.

Also check this topic. And check Icaro's answer's comments.

Take a look to StringBuilder too.

String concatenation with + vs. f-string

There are two aspects to this: performance and convenience.

Using timeit in Python 3.8.0, I get that concatenation using an f-string is consistently slower than +, but the percentage difference is small for longer strings:

>>> from timeit import timeit
>>> timeit('a + b', setup='a, b = "hello", "world"')
0.059246900000289315
>>> timeit('f"{a}{b}"', setup='a, b = "hello", "world"')
0.06997206999949412
>>> timeit('a + b', setup='a, b = "hello"*100, "world"*100')
0.10218418099975679
>>> timeit('f"{a}{b}"', setup='a, b = "hello"*100, "world"*100')
0.1108272269993904
>>> timeit('a + b', setup='a, b = "hello"*10000, "world"*10000')
2.6094200410007033
>>> timeit('f"{a}{b}"', setup='a, b = "hello"*10000, "world"*10000')
2.7300010479993944

However, the f-string may be a bit more convenient when your inputs aren't already strings:

>>> a, b = [1, 2, 3], True
>>> str(a) + str(b)
'[1, 2, 3]True'
>>> f'{a}{b}'
'[1, 2, 3]True'

Is it more Pythonic to use String Formatting over String Concatenation in Python 3?

Depends upon how long your string is and how many variables. For your use case I believe string.format is better as it has a better performance and looks cleaner to read.

Sometimes for longer strings + looks cleaner because the position of the variables are preserved where they should be in the string and you don't have to move your eyes around to map the position of {} to the corresponding variable.

If you can manage to upgrade to Python 3.6 you can use the newer more intuitive string formatting syntax like below and have best of both worlds:

player = 'Arbiter'
health = 100
print(f'{player} has {health} health left.')

If you have a very large string, I recommend to use a template engine like Jinja2 (http://jinja.pocoo.org/docs/dev/) or something along the line.

Ref: https://www.python.org/dev/peps/pep-0498/

When is it better to use String.Format vs string concatenation?

Before C# 6

To be honest, I think the first version is simpler - although I'd simplify it to:

xlsSheet.Write("C" + rowIndex, null, title);

I suspect other answers may talk about the performance hit, but to be honest it'll be minimal if present at all - and this concatenation version doesn't need to parse the format string.

Format strings are great for purposes of localisation etc, but in a case like this concatenation is simpler and works just as well.

With C# 6

String interpolation makes a lot of things simpler to read in C# 6. In this case, your second code becomes:

xlsSheet.Write($"C{rowIndex}", null, title);

which is probably the best option, IMO.

String.format() vs string concatenation performance

The second one will be even slower (if you look at the source code of String.format() you will see why). It is just because String.format() executes much more code than the simple concatenation. And at the end of the day, both code versions create 3 instances of String. There are other reasons, not performance related, to use String.format(), as others already pointed out.



Related Topics



Leave a reply



Submit