print#两个列表都是长整数值列表 print lstBitsBitwiseAnd [0:3] print lstBitsModulo [0:3] 解决方案 >下面的测试代码显示,使用n& 0x01时,从使用n& 0x01的整数值中提取位比使用n%2时更快,我认为它是因为%2试图处理整个整数,其中& 0x01只处理它的最后两个字节(我来这是因为& 0x01和%2操作之间的速度差异取决于它的大小。价值n是) 我怀疑原因是&处理较少的数据。原因是%有效地是一个分区,而&是一个逻辑操作。这总是比分裂更快_ /> 。 当然你是正确的,当一个人的bfiddling _could_优化 知道只有某个数字的某些字节才会引起关注。但是我很担心python会在这里进行任何优化。但是,我肯定不知道。 问候, Diez 我不知道如何直接访问 long的内部结构,但你可以加速你的例子。 首先,是命令的顺序 i = i>> 1 lstBitsBitwiseAnd.append(i& 0x01) 你想要什么?第一个低位被丢弃,因为你已经先完成了这个班次。并附加一个额外的0。 如果你想获得long的二进制表示,请尝试 i .__ hex __()。这将创建一个带有十六进制表示的字符串。 从十六进制到二进制的转换留给读者练习。 :-) ca **** @ comcast.net 写道:我不知道如何直接访问的内部结构,但你可以加快你的榜样。 首先是命令的顺序 i = i>> 1 lstBitsBitwiseAnd.append(i& 0x01) 你想要什么?第一个低位被丢弃,因为你已经先完成了这个班次。并附加一个额外的0。 如果你想获得long的二进制表示,请尝试使用 i .__ hex __()。这将创建一个带有十六进制表示的字符串。从十六进制到二进制的转换留给读者练习。 : - ) 你是对的,如果你想从 整数值中取出所有位,这是不正确的。我没有注意到正确的顺序,因为我的 唯一的目的是检查什么是更快的模除法或按位 - 和 所以结果这个顺序没关系。 i .__ hex __()的想法非常非常接近我最初的要求 for。遗憾的是,它通常被认为不比使用+ b $ b转换+按位的速度更快 - 后者似乎优于 小长整数和整数(参见附加代码显示中断甚至 ,对于需要超过16到104位数的整数,对于我机器上的多个测试,需要超过)。 克劳迪奥 导入时间 dctLstOfBitsVsCharOfNibble = {} #dctLstOfBitsVsCharOfNibble是一个带有键的字典。 字符 #表示半字节的十六进制值的字符串和一个值为列表的值 半字节的位数,其中最低位存储在 列表的索引0处。 #ie 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] } #字典可以也可以生成例如使用以下代码: #dctLstOfBitsVsCharOfNibble = {} #for intNibbleValue in range(0,16): #lstBitReprOfCurrNibble = [] #对于范围(0,4)中的indxOfBit: #lstBitReprOfCurrNibble.append(intNibbleValue>> indx OfBit& 0x01) ## :for #lstBitReprOfCurrNibble.reverse() # dctLstOfBitsVsCharOfNibble [''%X''%(intNibbleValue,)] = lstBitReprOfCurrNibble ##:for NoOf32bitChunksOfInteger = 0 n = 0 lstBitsBitwiseAnd = [] lstBitsModulo = [] lstBitsViaHex = [] timeBitwiseAnd = -1 timeModulo = -1 timeBitsViaHex = -1 而timeBitwiseAnd< = timeBitsViaHex: n =(n<< 32)+ 0x12345678 NoOf32bitChunksOfInteger + = 1 i = n lstBitsModulo = [] start = time.clock () 而我: 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:] 如果strHexOf_i [-1] ==''L'': strHexOf_i = strHexOf_i [0:-1] #:if intNoOfLeadingZeroBits = 0 lstBitsOfFirstNibble = dctLstOfBitsVsCharOfNibble [strHexOf_i [0]] 而不是lstBitsOfFirstNibble [ intNoOfLeadingZeroBits]和 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() - 开始 #:而 如果是lstBitsBitwiseAnd == lstBitsModulo和lstBitsBitwiseAnd == lstBitsViaHex: print print''从整数中提取位的秒数,%i为十六位数 时:''%(NoOf32bitChunksOfInteger * 8,) 打印 打印''循环播放i>> 1; i& 0x01 = %f''%(timeBitwiseAnd,) 打印''循环播放i>> 1; i %% 2 =%f''%(timeModulo,) 打印''使用i .__ hex __()repr。 =%f''%(timeBitsViaHex,) 打印 打印''对于长整数我有十六进制数字'' 打印''> %i''%(NoOf32bitChunksOfInteger * 8,) print''使用i .__ hex __()进行位提取比使用 i>> 1; i& 0x01。'' 打印 打印''Modulo除法(%)总是慢于按位和 (&)。 '' Let''s consider a test source code given at the very end of this posting.The question is if Python allows somehow access to the bytes of therepresentation of a long integer or integer in computers memory?Or does Python hide such implementation details that deep, that there isno way to get down to them?The test code below shows, that extracting bits from an integer value nis faster when using n&0x01 than when using n%2 and I suppose it isbecause %2 tries to handle the entire integer, where &0x01 processesonly the last two bytes of it (I come to this because the speeddifference between &0x01 and %2 operations depends on how large thevalue n is). If it were possible to ''tell'' the %2 operation to operateonly on one short of the integer number representation there will beprobably no difference in speed. Is there a way to do this efficientlyin Python like it is possible in C when using pointers and recasting?As I am on Python 2.4.2 and Microsoft Windows, I am interested indetails related to this Python version (to limit the scope of thequestion).ClaudioHere the code:import time# i = 2**25964951 - 1i = 123456789**123lstBitsModulo = []start = time.clock()while i:i=i>>1lstBitsModulo.append(i%2)speedModulo = time.clock()-start# i = 2**25964951 - 1i = 123456789**123lstBitsBitwiseAnd = []start = time.clock()while i:i=i>>1lstBitsBitwiseAnd.append(i&0x01)speedBitwiseAnd = time.clock()-startprintif lstBitsBitwiseAnd == lstBitsModulo :print ''BitwiseAnd = %f ''%(speedBitwiseAnd,)print ''Modulo = %f ''%(speedModulo,)print # both lists are lists of long integer valuesprint lstBitsBitwiseAnd[0:3]print lstBitsModulo[0:3] 解决方案 > The test code below shows, that extracting bits from an integer value n is faster when using n&0x01 than when using n%2 and I suppose it is because %2 tries to handle the entire integer, where &0x01 processes only the last two bytes of it (I come to this because the speed difference between &0x01 and %2 operations depends on how large the value n is)I doubt that the reason is in & handling less data. The reason is that % iseffectively a division, whereas & is a logical operation. Which have alwaysbeen _way_ faster than divisions.Of course you are right that the bitfiddling _could_ be optimized when oneknows that only certain bytes of a number would be of interest. But Iseriously doubt that python does any optimization here. However, I don''tknow for sure.Regards,DiezI don''t know of a way to directly access the internal structure of along, 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''vedone the shift first. And an extra 0 is appended.If you are trying to get the binary representation of a long, tryi.__hex__(). This will create a string with the hex representation.Conversion from hex to binary is left as an exercise for the reader. :-) ca****@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 aninteger value. I haven''t payed attention to the proper order, because myonly 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 askedfor. It''s a pity, that it can''t be generally considered faster thanusage of shifting+bitwise-and where the latter seem to be superior forsmall long integers and integers (see attached code showing a break evenfor integers which require more than appr. 16 up to 104 digits accordingto multiple tests on my machine).Claudioimport timedctLstOfBitsVsCharOfNibble = {}# dctLstOfBitsVsCharOfNibble is a dictionary with a key beeing onecharacter# string representing hexadecimal value of a nibble and a value beeing alist# of bits of the nibble where the lowest bit is stored at index 0 of thelist.# 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>>indx OfBit&0x01)# #:for# lstBitReprOfCurrNibble.reverse()#dctLstOfBitsVsCharOfNibble[''%X''%(intNibbleValue,)]=lstBitReprOfCurrNibble# #:forNoOf32bitChunksOfInteger = 0n = 0lstBitsBitwiseAnd = []lstBitsModulo = []lstBitsViaHex = []timeBitwiseAnd = -1timeModulo = -1timeBitsViaHex = -1while timeBitwiseAnd <= timeBitsViaHex:n = (n<<32) + 0x12345678NoOf32bitChunksOfInteger += 1i = nlstBitsModulo = []start = time.clock()while i:lstBitsModulo.append(i%2)i=i>>1timeModulo = time.clock()-starti = nlstBitsBitwiseAnd = []start = time.clock()while i:lstBitsBitwiseAnd.append(i&0x01)i=i>>1timeBitwiseAnd = time.clock()-starti = n# lstBitsViaHex = []start = time.clock()strHexOf_i = i.__hex__()[2:]if strHexOf_i[-1]==''L'':strHexOf_i=strHexOf_i[0:-1]#:ifintNoOfLeadingZeroBits = 0lstBitsOfFirstNibble = dctLstOfBitsVsCharOfNibble[strHexOf_i[0]]while not lstBitsOfFirstNibble[intNoOfLeadingZeroBits] andintNoOfLeadingZeroBits < 4:intNoOfLeadingZeroBits += 1#:whileif intNoOfLeadingZeroBits == 4:lstBitsViaHex = []else:lstBitsViaHex = lstBitsOfFirstNibble[intNoOfLeadingZeroBits:]#:iffor indxToStrHexOf_i in range(1,len(strHexOf_i)):lstBitsViaHex +=dctLstOfBitsVsCharOfNibble[strHexOf_i[indxToStrHexOf_i]]#:forlstBitsViaHex.reverse()timeBitsViaHex = time.clock()-start#:whileif lstBitsBitwiseAnd == lstBitsModulo and lstBitsBitwiseAnd ==lstBitsViaHex:printprint '' Seconds for bit extraction from integer with %i hex-digitswhen: ''%(NoOf32bitChunksOfInteger*8,)printprint '' looping over i>>1;i&0x01 = %f ''%(timeBitwiseAnd,)print '' looping over i>>1;i%%2 = %f ''%(timeModulo,)print '' using i.__hex__() repr. = %f ''%(timeBitsViaHex,)printprint '' For long integers i with number of hexadecimal digits ''print '' > %i ''%(NoOf32bitChunksOfInteger*8,)print '' bits extraction with i.__hex__() is faster then withi>>1;i&0x01 .''printprint '' Modulo division (%) is always much slower than bitwise and(&). '' 这篇关于Python是否允许访问某些实现细节?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云! 07-30 14:10