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.
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)
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
When should I use String.Format or String.Concat instead of the concatenation operator?
Concerning speed it almost always doesn't matter.
var answer = "Use what makes " + "the code most easy " + "to read";
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
Are there benefits to using string formatting versus string concatenation?
For me, the benefits of the string.Format
pendant are:
- Improved readability
- Better translatable
From a performance perspective, I did never do any measurements; it could well be that the concatenation is faster then the string.Format
pendant.
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 ;)
String Interpolation vs String.Format
The answer is both yes and no. ReSharper
is fooling you by not showing a third variant, which is also the most performant. The two listed variants produce equal IL code, but the following will indeed give a boost:
myString += $"{x.ToString("x2")}";
Full test code
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Configs;
using BenchmarkDotNet.Diagnosers;
using BenchmarkDotNet.Diagnostics.Windows;
using BenchmarkDotNet.Running;
namespace StringFormatPerformanceTest
{
[Config(typeof(Config))]
public class StringTests
{
private class Config : ManualConfig
{
public Config() => AddDiagnoser(MemoryDiagnoser.Default, new EtwProfiler());
}
[Params(42, 1337)]
public int Data;
[Benchmark] public string Format() => string.Format("{0:x2}", Data);
[Benchmark] public string Interpolate() => $"{Data:x2}";
[Benchmark] public string InterpolateExplicit() => $"{Data.ToString("x2")}";
}
class Program
{
static void Main(string[] args)
{
var summary = BenchmarkRunner.Run<StringTests>();
}
}
}
Test results
| Method | Data | Mean | Gen 0 | Allocated |
|-------------------- |----- |----------:|-------:|----------:|
| Format | 42 | 118.03 ns | 0.0178 | 56 B |
| Interpolate | 42 | 118.36 ns | 0.0178 | 56 B |
| InterpolateExplicit | 42 | 37.01 ns | 0.0102 | 32 B |
| Format | 1337 | 117.46 ns | 0.0176 | 56 B |
| Interpolate | 1337 | 113.86 ns | 0.0178 | 56 B |
| InterpolateExplicit | 1337 | 38.73 ns | 0.0102 | 32 B |
New test results (.NET 6)
Re-ran the test on .NET 6.0.9.41905, X64 RyuJIT AVX2
.
| Method | Data | Mean | Gen0 | Allocated |
|-------------------- |----- |---------:|-------:|----------:|
| Format | 42 | 37.47 ns | 0.0089 | 56 B |
| Interpolate | 42 | 57.61 ns | 0.0050 | 32 B |
| InterpolateExplicit | 42 | 11.46 ns | 0.0051 | 32 B |
| Format | 1337 | 39.49 ns | 0.0089 | 56 B |
| Interpolate | 1337 | 59.98 ns | 0.0050 | 32 B |
| InterpolateExplicit | 1337 | 12.85 ns | 0.0051 | 32 B |
The InterpolateExplicit()
method is faster since we now explicitly tell the compiler to use a string
. No need to box the object to be formatted. Boxing is indeed very costly. Also, note that pre-NET6 we reduced the allocations a bit.
Related Topics
How to Set a Program to Launch at Startup
What Is the Use of "Ref" for Reference-Type Variables in C#
Programmatically Determine a Duration of a Locked Workstation
How to Run an Exe File from My C# Code
C# Convert String from Utf-8 to Iso-8859-1 (Latin1) H
Accessing UI (Main) Thread Safely in Wpf
How to Add a Blend Behavior in a Style Setter
How to Return a String Repeated X Number of Times
Reflection to Identify Extension Methods
What Is "Best Practice" for Comparing Two Instances of a Reference Type
Serializing and Deserializing Expression Trees in C#
How to Get Memory Available or Used in C#
How to Overload the Square-Bracket Operator in C#
Is Int[] a Reference Type or a Value Type
Excel Interop - Efficiency and Performance