Does Python allow access to some of the implementation details?
Claudio Grondi
claudio.grondi at freenet.de
Fri Jan 6 16:09:41 EST 2006
casevh at comcast.net wrote:
> I don't know of a way to directly access the internal structure of a
> long, but you can speed up your example.
>
> First, is the order of the commands
>
>
>> i=i>>1
>> lstBitsBitwiseAnd.append(i&0x01)
>
>
> what you intend? The first low order bit is discarded because you've
> done the shift first. And an extra 0 is appended.
>
> If you are trying to get the binary representation of a long, try
> i.__hex__(). This will create a string with the hex representation.
> Conversion from hex to binary is left as an exercise for the reader. :-)
>
You are right, it is not correct if you want to get all bits out of an
integer value. I haven't payed attention to the proper order, because my
only intent was to check what is faster modulo-division or bitwise-and,
so for the outcome of this the order does not matter.
The i.__hex__() idea is very, very near to what I have originally asked
for. It's a pity, that it can't be generally considered faster than
usage of shifting+bitwise-and where the latter seem to be superior for
small long integers and integers (see attached code showing a break even
for integers which require more than appr. 16 up to 104 digits according
to multiple tests on my machine).
Claudio
import time
dctLstOfBitsVsCharOfNibble = {}
# dctLstOfBitsVsCharOfNibble is a dictionary with a key beeing one
character
# string representing hexadecimal value of a nibble and a value beeing a
list
# of bits of the nibble where the lowest bit is stored at index 0 of the
list.
# i.e.
dctLstOfBitsVsCharOfNibble = {
'0':[0, 0, 0, 0],
'1':[0, 0, 0, 1],
'2':[0, 0, 1, 0],
'3':[0, 0, 1, 1],
'4':[0, 1, 0, 0],
'5':[0, 1, 0, 1],
'6':[0, 1, 1, 0],
'7':[0, 1, 1, 1],
'8':[1, 0, 0, 0],
'9':[1, 0, 0, 1],
'A':[1, 0, 1, 0],
'B':[1, 0, 1, 1],
'C':[1, 1, 0, 0],
'D':[1, 1, 0, 1],
'E':[1, 1, 1, 0],
'F':[1, 1, 1, 1]
}
# The dictionary can also be generated e.g. using following code:
# dctLstOfBitsVsCharOfNibble = {}
# for intNibbleValue in range(0, 16):
# lstBitReprOfCurrNibble=[]
# for indxOfBit in range(0,4):
# lstBitReprOfCurrNibble.append(intNibbleValue>>indxOfBit&0x01)
# #:for
# lstBitReprOfCurrNibble.reverse()
#
dctLstOfBitsVsCharOfNibble['%X'%(intNibbleValue,)]=lstBitReprOfCurrNibble
# #:for
NoOf32bitChunksOfInteger = 0
n = 0
lstBitsBitwiseAnd = []
lstBitsModulo = []
lstBitsViaHex = []
timeBitwiseAnd = -1
timeModulo = -1
timeBitsViaHex = -1
while timeBitwiseAnd <= timeBitsViaHex:
n = (n<<32) + 0x12345678
NoOf32bitChunksOfInteger += 1
i = n
lstBitsModulo = []
start = time.clock()
while i:
lstBitsModulo.append(i%2)
i=i>>1
timeModulo = time.clock()-start
i = n
lstBitsBitwiseAnd = []
start = time.clock()
while i:
lstBitsBitwiseAnd.append(i&0x01)
i=i>>1
timeBitwiseAnd = time.clock()-start
i = n
# lstBitsViaHex = []
start = time.clock()
strHexOf_i = i.__hex__()[2:]
if strHexOf_i[-1]=='L':
strHexOf_i=strHexOf_i[0:-1]
#:if
intNoOfLeadingZeroBits = 0
lstBitsOfFirstNibble = dctLstOfBitsVsCharOfNibble[strHexOf_i[0]]
while not lstBitsOfFirstNibble[intNoOfLeadingZeroBits] and
intNoOfLeadingZeroBits < 4:
intNoOfLeadingZeroBits += 1
#:while
if intNoOfLeadingZeroBits == 4:
lstBitsViaHex = []
else:
lstBitsViaHex = lstBitsOfFirstNibble[intNoOfLeadingZeroBits:]
#:if
for indxToStrHexOf_i in range(1,len(strHexOf_i)):
lstBitsViaHex +=
dctLstOfBitsVsCharOfNibble[strHexOf_i[indxToStrHexOf_i]]
#:for
lstBitsViaHex.reverse()
timeBitsViaHex = time.clock()-start
#:while
if lstBitsBitwiseAnd == lstBitsModulo and lstBitsBitwiseAnd ==
lstBitsViaHex:
print
print ' Seconds for bit extraction from integer with %i hex-digits
when: '%(NoOf32bitChunksOfInteger*8,)
print
print ' looping over i>>1;i&0x01 = %f '%(timeBitwiseAnd,)
print ' looping over i>>1;i%%2 = %f '%(timeModulo,)
print ' using i.__hex__() repr. = %f '%(timeBitsViaHex,)
print
print ' For long integers i with number of hexadecimal digits '
print ' > %i '%(NoOf32bitChunksOfInteger*8,)
print ' bits extraction with i.__hex__() is faster then with
i>>1;i&0x01 .'
print
print ' Modulo division (%) is always much slower than bitwise and
(&). '
More information about the Python-list
mailing list