Though I wouldn't suspect a large discrepancy between these, they are obviously slightly different.
A print
call that concatenates literal strings might be joined by CPython's peephole optimizer before being printed thereby resulting in faster execution, this is probably what you're seeing. Besides that, with small strings, the fact that only one argument is passed and, as a result, sep
isn't used is also a small benefit.
With larger strings, the need to create a large temporary string to hold their concatenation negates all speed differences achieved. (The fact that sep
isn't used and only one argument is passed is trumped due to the size and their concatenation)
Using ,
in a print call will pass each string as an argument and separate it using the default sep
. While this obviously requires a bit more work, it is constant work that, again, disappears when large strings are involved.
So, with small strings that actually get caught by the optimizer, concatenation is a bit faster:
%timeit print("a" + "b", file=f)
1000000 loops, best of 3: 1.76 μs per loop
%timeit print("a", "b", sep='', file=f)
100000 loops, best of 3: 2.48 μs per loop
Even when the optimizer can't join them:
a = "a"; b = "b"
%timeit print(a + b, file=f)
1000000 loops, best of 3: 2 μs per loop
%timeit print(a, b, sep='', file=f)
100000 loops, best of 3: 2.45 μs per loop
when the string sizes increase, this small difference is eclipsed:
s1, s2 = "s" * 100000, "s"*100000
%timeit print(s1 + s2, file=f)
1000 loops, best of 3: 374 μs per loop
%timeit print(s1, s2, sep='', file=f)
1000 loops, best of 3: 373 μs per loop