Could someone please explain #Test 11. How is using %s instead of %d double as fast even though it is the same thing is being calculated? I always use %d because it seems like the prooper way to do it.
The function PyString_Format (Objects/stringobject.c) does the formatting for the % operator. For %s it calls _PyObject_Str which in turn calls "str()" on the object. For %d it calls formatint (located in the same file).
The str() implementation for ints is in int_to_decimal_string (Objects/intobject.c) and it's incredibly simple:
do {
*--p = '0' + (char)(absn % 10);
absn /= 10;
} while (absn);
The code for formatint is way more complex, and it contains two call to the native snprintf:
The native snprintf is heavier because it handles precision, zero-padding and stuff like that.
I believe this is why %d is slower. %s is a straight "devide-by-10-and-subtract" loop while %d are two library calls to the full-blown sprintf. However I didn't actually profile the code because I don't have a debug build, so I might be completely wrong.
The function PyString_Format (Objects/stringobject.c) does the formatting for the % operator. For %s it calls _PyObject_Str which in turn calls "str()" on the object. For %d it calls formatint (located in the same file).
The str() implementation for ints is in int_to_decimal_string (Objects/intobject.c) and it's incredibly simple:
The code for formatint is way more complex, and it contains two call to the native snprintf: The native snprintf is heavier because it handles precision, zero-padding and stuff like that.I believe this is why %d is slower. %s is a straight "devide-by-10-and-subtract" loop while %d are two library calls to the full-blown sprintf. However I didn't actually profile the code because I don't have a debug build, so I might be completely wrong.
Edit: Link to code: https://github.com/python/cpython/blob/a5c7a4257507a77699a1a...