What's the difference between i1 and i2 in Python 3? Why is i1 faster? Is one of the two better?
https://docs.python.org/3/library/struct.html#format-characters
import struct, timeit
print("i1 in %s" % timeit.timeit(
"struct.unpack('<I', b'\\x3C\\x5B\\x01\\x00')",
globals=globals(), number=10000000))
print("i2 in %s" % timeit.timeit(
"struct.unpack('<I', b'\\x3C\\x5B\\x01\\x00')",
globals=globals(), number=10000000))
i1 = struct.unpack('<I', b"\x3C\x5B\x01\x00")[0]
i2 = struct.unpack('<L', b"\x3C\x5B\x01\x00")[0]
print(i1, type(i1), i2, type(i2))
Output:
i1 in 1.336791369
i2 in 1.430974416
88892 <class 'int'> 88892 <class 'int'>
CodePudding user response:
The labels ‘int’ and ‘long’ found in the struct
module’s documentation do not refer to the Python type int
and Python 2 type long
, but to C types int
and long
. The bit widths of those types depend on the platform ABI; these days, int
is commonly 32 bits wide, while long
is usually either 32 or 64 bits wide.
Enabling any of the ‘standard sizes’ options (<
, >
or =
) switches the struct
module to conform to an IL32 ABI, in which both int
and long
are 32 bits wide, and only long long
is 64 bits wide. As such, in those modes there is no difference between I
and L
, and to pack or unpack a 64-bit value in those modes, the q
(long long
) specifier is needed. However, when operating in the default ‘native sizes’ mode (@
), the sizes of I
and L
may be different. For example, on my x86-64 Linux system, I get this:
>>> struct.pack('@L', 0)
b'\x00\x00\x00\x00\x00\x00\x00\x00'
>>> struct.pack('@I', 0)
b'\x00\x00\x00\x00'
As 64-bit Linux is an LP64 platform, the width of long
is 64 bits, while the width of int
is 32 bits. 64-bit Windows, on the other hand, is an LLP64 platform, on which long
is 32 bits wide.