What is the difference between writing a null byte with:
print("\x00")
And writing one with:
print(struct.pack("B", 0))
I've taken the liberty of timing both of their execution times with the following:
def struct_exec_time():
start_time = time.time()
import struct
print(struct.pack("B",0))
return time.time() - start_time
def simple_print_exec():
start_time = time.time()
print("\x00")
return time.time() - start_time
When running them both:
>>> for _ in range(1):
... print("Struct execution time: {}".format(struct_exec_time()))
... print("Simple print execution time: {}".format(simple_print_exec()))
...
Struct execution time: 2.38418579102e-05
Simple print execution time: 3.09944152832e-06
>>>
It seems that struct is faster then the print function for the first execution, because if you run them more then once:
>>> for _ in range(5):
... print("Struct execution time: {}".format(struct_exec_time()))
... print("Simple print execution time: {}".format(simple_print_exec()))
...
Struct execution time: 2.71797180176e-05
Simple print execution time: 5.00679016113e-06
Struct execution time: 9.05990600586e-06
Simple print execution time: 4.05311584473e-06
Struct execution time: 7.15255737305e-06
Simple print execution time: 5.00679016113e-06
Struct execution time: 7.15255737305e-06
Simple print execution time: 4.05311584473e-06
Struct execution time: 6.91413879395e-06
Simple print execution time: 4.76837158203e-06
So, what is the difference between the two, and why is struct only faster then print once?
Edit:
With the import struct
call taken out of the timer:
def struct_exec_time():
import struct
start_time = time.time()
print(struct.pack("B",0))
return time.time() - start_time
for _ in range(5):
print("Struct exec: {}".format(struct_exec_time()))
print("Print exec: {}".format(simple_print_exec()))
Struct exec: 3.40938568115e-05
Print exec: 2.86102294922e-06
Struct exec: 2.86102294922e-06
Print exec: 3.09944152832e-06
Struct exec: 2.86102294922e-06
Print exec: 3.09944152832e-06
Struct exec: 3.81469726562e-06
Print exec: 3.09944152832e-06
Struct exec: 2.86102294922e-06
Print exec: 2.14576721191e-06
If you are using Python 2.7 the two values are equal and of the same type: str
(= Python 3 bytes
).
Here is a python 2/3 test:
import struct
b1 = struct.pack('B', 0)
b2 = b'\x00'
assert b1 == b2
assert type(b1) == type(b2)
In every day programming I would prefer using a bytes string instead of using struct
.
Quoting the documentation:
This module performs conversions between Python values and C structs represented as Python bytes objects.
Edit
Note about performance: b’\x00’ is a literal. Compared to a function call, the evaluation of a literal is always faster.