2的补码转换.这是对的吗?

我正在阅读文件中的3字节号,它们已签名(+8至
-80万).这似乎有效,但我不确定是正确的.
#将3个字符转换为一个数字.
value1,value2,value3 = uncack("> bbb",buffer [s:s+3])
值=(value1*65536)+(value2*256)+value3
如果值> = 0x800000:
值 - = 0x1000000
打印值
例如:
16682720 = -94496
应该是值 - = 0x1000001,以便我得到-94497吗?
谢谢!
鲍勃

# 回答1


在2008-04-18,鲍勃·格雷斯克(Bob Greschke) 没有. -94496是正确的答案:
16682720
这是另一种方法:
------------------------------------------------------------------------------------ ------------------------
导入结构
def tohex(s):
返回'0x' +''.join([['%0.2X'%ORD(b)的b])
def from3bytes(s):
#符号在s中扩展了三个字节号以使其长4个字节长
如果ORD(S [0])和0x80:
s ='\ xff'+s
别的:
s ='\ x00'+s
返回struct.unpack('> i',s)[0]
对于v in 0,1,-2,500,-500,7777,-7777,-7777,-94496,98765,-98765,8388607,-8388607,-8388607,-8388608:
s = struct.pack('> i',v)[1:]
打印"%8D%s%8D"%(v,tohex(s),从3bytes(s))
------------------------------------------------------------------------------------ ------------------------
- -
格兰特·爱德华兹·格兰特·尤!我会吃任何东西
在那是明亮的蓝色!
visi.com
# 回答2


鲍勃·格雷斯克(Bob Greschke) 您的第一种情况是正确的,"值 - = 0x1000000".值0xffffff
应为-1和0xffffff -0x1000000 == -1.
另一种做到这一点的方式:
value = unwack("> l",缓冲区[s:s + 3] +" \ 0")[0]> 8
罗斯·里奇
- -
l/ //罗斯·里奇(Ross Ridge) - 伟大的HTMU
[oo] [oo] rrxplub.uwaterloo.ca
- () - /()/http://www.csclub.uwaterloo.ca/~rridge/
D b //
# 回答3


在2008-04-18 14:37:21 -0600,罗斯里奇
您的第一种情况是正确的,"值 - = 0x1000000".值0xffffff
应为-1和0xffffff -0x1000000 == -1.
另一种做到这一点的方式:
value = unwack("> l",缓冲区[s:s + 3] +" \ 0")[0]> 8
罗斯·里奇
很高兴知道(在数学方面从来都不是很好).
但是,在玩弄您的建议和赠款的代码时
发现结构的东西比这样做要慢得多
value =(ord(buf [s])*65536)+(ord(buf [s+1])*256)+ord(buf [s+2])
如果值> = 0x800000:
值 - = 0x1000000
这几乎是坐在这里的几乎是两倍
十万个转换(例如3秒钟和〜5秒刚刚指望我
手指 - 在旧的太阳上...有点慢).用<< 16代替 *65536
*256带有<< 8的256甚至可能更快一些,但它太近了
致电而无需真正分析.
我不打算今天进行这一发现! :)
鲍勃
# 回答4


4月18日,5:26*下午,鲍勃·格雷斯克(Bob Greschke) 很高兴知道(在数学方面从来都不是很好).
但是,在玩弄您的建议和赠款的代码时
发现结构的东西比这样做要慢得多
*value =(ord(buf [s])*6 5536)+(ord(buf [s+1])*256)+ord(buf [s+2])
*如果值> = 0x800000:
* * *值 - = 0x1000000
这几乎是坐在这里的几乎是两倍
十万个转换(例如3秒钟和〜5秒刚刚指望我
手指 - 在旧的太阳上...有点慢). *
您最好使用一种比手指计数更精确的计时方法,
例如时间段.速度的两倍可能是高估.上
我的盒子(python 2.5,winxp)避免打开包装约为10%和40%
分别与罗斯和格兰特的方法更快:
python -m timeit" for i in xrange(1000):from3bytes_bob(s)" \
-s"来自bin import *; s = pack('> i',1234567)[1:]"
1000循环,最佳3:1.02毫秒 /循环
python -m timeit" for i in xrange(1000):from3bytes_grant(s)" \
-s"来自bin import *; s = pack('> i',1234567)[1:]"
1000循环,最佳3:1.43毫秒 /循环
python -m timeit" for i in xrange(1000):from3bytes_ross(s)" \
-s"来自bin import *; s = pack('> i',1234567)[1:]"
1000循环,最佳3:1.12毫秒 /循环
### bin.py #################################################
从struct导入打开包装
From3Bytes_Bob(S)的def:
value =(ord(s [0])<< 16) +(ord(s [1])<< 8) + ord(s [2])
如果值> = 0x800000:
值 - = 0x1000000
返回值
From3Bytes_Grant(S)的def:
如果ORD(S [0])和0x80:
s ='\ xff'+s
别的:
s ='\ x00'+s
返回打开包装('> i',s)[0]
def from3bytes_ross(s):
返回拆卸("> l",s +" \ 0")[0]> 8
如果您在32位体系结构上运行此操作,请获取Psyco [1]和
添加在模块的顶部:
进口psyco; psyco.full()
在此场景中使用psyco的速度高达70%:
python -m timeit" for i in xrange(1000):from3bytes_bob(s)" \
-s"来自bin import *; s = pack('> i',1234567)[1:]"
1000循环,最佳3:624 USEC每循环
python -m timeit" for i in xrange(1000):from3bytes_grant(s)" \
-s"来自bin import *; s = pack('> i',1234567)[1:]"
1000循环,最佳3:838 USEC每循环
python -m timeit" for i in xrange(1000):from3bytes_ross(s)" \
-s"来自bin import *; s = pack('> i',1234567)[1:]"
1000循环,最佳3:834 USEC每循环
乔治
[1] http://psyco.sourceforge.net/
# 回答5


在2008-04-18 16:04:37 -0600,George Sakkis ff
Oss Ridge
您最好使用一种比手指计数更精确的计时方法,
例如时间段.速度的两倍可能是高估.上
我的盒子(python 2.5,winxp)避免打开包装约为10%和40%
分别与罗斯和格兰特的方法更快:
python -m timeit" for i in xrange(1000):from3bytes_bob(s)" \
-s"来自bin import *; s = pack('> i',1234567)[1:]"
1000循环,最佳3:1.02毫秒 /循环
python -m timeit" for i in xrange(1000):from3bytes_grant(s)" \
-s"来自bin import *; s = pack('> i',1234567)[1:]"
1000循环,最佳3:1.43毫秒 /循环
python -m timeit" for i in xrange(1000):from3bytes_ross(s)" \
-s"来自bin import *; s = pack('> i',1234567)[1:]"
1000循环,最佳3:1.12毫秒 /循环
### bin.py #################################################
从struct导入打开包装
def for m3bytes_bob(S):
value =(ord(s [0])<< 16) +(ord(s [1])<< 8) + ord(s [2])
如果值> = 0x800000:
值 - = 0x1000000
返回值
From3Bytes_Grant(S)的def:
如果ORD(S [0])和0x80:
s ='\ xff'+s
别的:
s ='\ x00'+s
返回打开包装('> i',s)[0]
def from3bytes_ross(s):
返回拆卸("> l",s +" \ 0")[0]> 8
如果您在32位体系结构上运行此操作,请获取Psyco [1]和
添加在模块的顶部:
进口psyco; psyco.full()
在此场景中使用psyco的速度高达70%:
python -m timeit" for i in xrange(1000):from3bytes_bob(s)" \
-s"来自bin import *; s = pack('> i',1234567)[1:]"
1000循环,最佳3:624 USEC每循环
python -m timeit" for i in xrange(1000):from3bytes_grant(s)" \
-s"来自bin import *; s = pack('> i',1234567)[1:]"
1000循环,最佳3:838 USEC每循环
python -m timeit" for i in xrange(1000):from3bytes_ross(s)" \
-s"来自bin import *; s = pack('> i',1234567)[1:]"
1000循环,最佳3:834 USEC每循环
乔治
[1] http://psyco.sourceforge.net/
我在python 2.3.4的Solaris 8上,当嘎嘎作响时,
从字面上看,数百万的地震数据手指样本
很好地指出区别. :)我会更多地研究一些
我们更大的更快的机器(没有-m选项
在阳光下:).太阳正是我所发展的.如果东西运行很快
足以让我在SSHED X11连接上保持清醒
应该在实际野外设备上更好地运行(MAC,Linuxes,
Winxps).
从来没有听说过Psyco.那很好!
谢谢!
鲍勃
# 回答6


George Sakkis ...
如果您的Python 2.5,以下是一个更快的版本:
从结构导入 *
uncack_i32be = struct("> l").拆开包装
From3Bytes_ross2(s)的def:
返回unpack_i32be(s +" \ 0")[0]> 8
罗斯·里奇
- -
l/ //罗斯·里奇(Ross Ridge) - 伟大的HTMU
[oo] [oo] rrxplub.uwaterloo.ca
- () - /()/http://www.csclub.uwaterloo.ca/~rridge/
D b //
# 回答7


在2008-04-18 17:55:32 -0600,罗斯里奇
...
如果您的Python 2.5,以下是一个更快的版本:
从结构导入 *
uncack_i32be = struct("> l").拆开包装
From3Bytes_ross2(s)的def:
返回unpack_i32be(s +" \ 0")[0]> 8
罗斯·里奇
这甚至不可理解.我想回到科博尔. :)
# 回答8


Ross Ridge 鲍勃·格雷斯克(Bob Greschke) 它与以前的版本相同,除了它"预编译"
struct.unpack()格式字符串.它的工作类似于Python的方式
处理正则表达式.
罗斯·里奇
- -
l/ //罗斯·里奇(Ross Ridge) - 伟大的HTMU
[oo] [oo] rrxplub.uwaterloo.ca
- () - /()/http://www.csclub.uwaterloo.ca/~rridge/
D b //
# 回答9


在2008-04-18,鲍勃·格雷斯克(Bob Greschke) 我不知道速度很重要.这可能有点
更快(取决于硬件):
value =(ord(buf [s])<< 16)| (ord(buf [s+1])<< 8)| ord( buf [s+2])
这也使意图更加明显(至少对我而言).
一个像样的C编译器会认识到<< 16和<< 8是
特殊,只是四处移动,而不是实际做
转移.我怀疑Python编译器会进行优化
那,但是转移通常仍然比乘以
(尽管再次,一个好的编译器会认识到乘以
到65536与16的移动相同,然后移动字节
大约).
- -
格兰特·爱德华兹·格兰特·尤! If elected, Zippy
在每一个的承诺
visi.com美国一名55岁
Houseboy ...
# 回答10


在2008-04-18,鲍勃·格雷斯克(Bob Greschke) 如果时间是问题,我可能会编写一个C程序来转换
文件从24位数字到32位数字.那你可以使用
numpy可以将它们的大量阵列加载到一个击中.
- -
格兰特·爱德华兹·格兰特·尤! ..他主导
在decade废的地铁现场.
visi.com
# 回答11


在2008年4月18日星期五22:30:45 -0500,格兰特·爱德华兹(Grant Edwards)写道:
值 - = 0x1000000,这几乎是坐在这里的速度几乎是两倍的快速转换(例如3sec vs.〜5sec,仅在Myfingers上计算MyFingers),在旧的太阳上……有点慢).用<< 16和 *256用<< 8代替 *65536甚至可能会更快一些,但是它太近了,而没有真正分析它.

我不知道速度很重要.这可能更快一点
(取决于硬件):
value =(ord(buf [s])<< 16)| (ord(buf [s+1])<< 8)| ord(buf [s+2])
这也使意图更加明显(至少对我而言).
一个像样的C编译器将认识到<< 16和<< 8是特殊的,并且
只是四处移动,而不是实际进行轮班.我怀疑
Python编译器会进行类似的优化,但移动仍在
通常比倍增的速度快(尽管再次,一个好的编译器会
认识到乘以65536与将16转移相同
只需移动字节)即可.
那么,为什么不将其放入C扩展中呢?
这比大多数人想象的要容易:

从3bytes.c<br />
============<br />
#include <python.h><br />
PyObject*<br />
来自3bytes(pyObject* self,pyobject* args)<br />
{<br />
const char * s;<br />
int len;<br />
如果(!<br />
返回null;<br />
长n =(s [0] << 16)| (S [1] << 8)| S [2];<br />
如果(n> = 0x800000)<br />
n- = 0x1000000;<br />
返回pyint_fromlong(n);<br />
}<br />
静态pymethoddef函数[] = {<br />
{" from3bytes",(pycfunction)从3bytes,meth_varargs},<br />
{null,null,0,null},<br />
};<br />
dl_export(void)<br />
init_from3bytes(void)<br />
{<br />
py_initmodule(" _来自3bytes",functions);<br />
}<br />
buildme.py<br />
==========<br />
导入操作系统<br />
导入系统<br />
从Distutils.core导入扩展,设置<br />
OS.CHDIR(OS.PATH.DIRNAME(OS.PATH.ABSPATH(__ file __)))<br />
sys.argv = [sys.argv [0],'build_ext','-i']<br />
设置(ext_modules = [extension('_ from3bytes',['from3Bytes.c']])))))))))

'python buildme.py'将创建'_from3bytes.so'文件
'从_from3Bytes从3Bytes导入的'将导入c优化函数
希望这可以帮助.
- - Ivan Illarionov

# 回答12


在2008年4月19日星期六04:45:54 +0000上,伊万·伊拉里奥夫(Ivan Illarionov)写道:我不知道速度很重要.这可能会更快一些(取决于硬件):value =(ord(buf [s])<< 16)| (ord(buf [s+1])<< 8)| ord(buf [s+2])也使意图更加明显(至少对我而言).一个体面的c编译器会认识到<< 16和<< 8是特殊的,而不是实际进行轮班.我怀疑thepython编译器会进行类似的优化,但是移动的速度仍然比乘以乘以更快(尽管同样,一个好的编译器会认识到,乘以65536的乘以与16的转移,并且在周围移动bytes相同).

那么,为什么不将其放入C扩展中呢?
这比大多数人想象的要容易:

从3bytes.c<br />
============<br />
#include <python.h><br />
PyObject*<br />
来自3bytes(pyObject* self,pyObject* args){<br />
    const char * s;<br />
    int len;<br />
    如果(!<br />
        返回null;<br />
    长n =(s [0] << 16)| (S [1] << 8)| S [2];如果(n> = 0x800000)<br />
        n- = 0x1000000;<br />
    返回pyint_fromlong(n);<br />
}<br />
静态pymethoddef函数[] = {<br />
    {" from3bytes",(pycfunction)来自3bytes,meth_varargs},{null,<br />
    null,0,null},,<br />
};<br />
dl_export(void)<br />
init_from3bytes(void)<br />
{<br />
    py_initmodule(" _来自3bytes",functions);<br />
}<br />
buildme.py<br />
==========<br />
导入操作系统<br />
导入系统<br />
从Distutils.core导入扩展,设置<br />
OS.CHDIR(OS.Path.dirname(OS.Path.Abs​​path(__ file __)))sys.argv =<br />
[sys.argv [0],'build_ext','-i']设置(ext_modules =<br />
[extension('_ from3bytes',[''from3bytes.c'])]

'python buildme.py'将创建'_from3bytes.so'file'来自_from3bytes
从3bytes导入将导入C优化函数
希望这可以帮助.
对不起,
正确的代码应该是:
PyObject*
来自3bytes(pyObject* self,pyobject* args)
{
const char * s;
int len;
如果(!
返回null;
long n =((((((unsigned char)s [0]))<< 16)|((((unsigned char)s [1])<< 8)|
((无符号字符)S [2]));
如果(n> = 0x800000)
n- = 0x1000000;
返回pyint_fromlong(n);
}

# 回答13


在2008-04-18 23:35:12 -0600,Ivan Illarionov 来自3Bytes.c =============== ! (S [1] << 8)| S [2]; if(n> = 0x800000)n- = 0x1000000; return pyint_fromlong(n);} static pymethoddef functions [] = {{{{" from3bytes",(pycfunction),3bytes,meth_varargs},null,null,null,null,null,null,null} ;<br /> dl_export(void)init_from3bytes(void){py_initmodule(" _ from3bytes",functions);} buildme.py =========================================== (os.path.abspath(__ file __)))sys.argv = [sys.argv [0],'build_ext','-i'] setup(ext_modules = [extension = [extension('_ _ from3bytes',['frof3Bytes.c'] )) 'python buildme.py'将创建'_from3bytes.so'file'文件'来自_from3bytesimport 从3Bytes的开始,将导入C型函数霍普,这会有所帮助.

对不起,
正确的代码应该是:
pyObject*来自3bytes(pyObject* self,pyobject* args)
{
const char * s;
int len;
如果(!
返回null;
long n =((((((unsigned char)s [0]))<< 16)|((((unsigned char)s [1])<< 8)|
((无符号字符)S [2]));
如果(n> = 0x800000)
n- = 0x1000000;
返回pyint_fromlong(n);
}
不,谢谢.能够更改和安装这些程序
他们安装的计算机比速度更重要.我去了
几年前,沿着C延伸道路变成了一团糟.
一切都必须在太阳,Mac,Linux和Windows上运行
大气术馆如果必须更改.我无法恢复一切
需要重建该程序以外安装Python和
TKINTER(以及一些程序的Pyserial和PIL),他们
需要运行.因此,没有编译,所有内容都在一个文件中,以防万一
新版本必须由用户通过电子邮件发送给他们来升级
他们坐在西藏的一些山上.只是解压缩,粘贴.py
在逻辑上(通常)双击的地方,它们正在关闭并运行.
鲍勃

# 回答14


在2008-04-18 21:33:34 -0600,Grant Edwards 如果时间是问题,我可能会编写一个C程序来转换
文件从24位数字到32位数字.那你可以使用
numpy可以将它们的大量阵列加载到一个击中.
是的,你可以. :)但是这一切都是实时的(就像'Gotta一样
现在是实时的).另外,我们正在处理100个文件
(乐器)一次.今年夏天将有1000件乐器
在加拿大.
这是该程序愉快地崩溃的几乎两倍
速度是昨天的前一天. www.greschke.com/unlinked/files/pocus.png
白点来自3字节的整数,构成了绿线
构成了一个"逻辑"块(在这种情况下,他们录制了
每次仪器一个文件的整个数据文件一次60分钟).
通常,我们只是快速看一下绿线,以确保
乐器正在工作,拔出坏的乐器,以免他们得到
再次使用,直到他们被检查为止.放大到其中的水平
您可以看到单独的样本习惯于(更多)准确
确定[故意]爆炸的时间.你
为此,使用放置在射击孔附近的乐器.简单的. :)
鲍勃
# 回答15


>
www.greschke.com/unlinked/images/pocus.png
# 回答16


4月18日,9:36*下午,罗斯里奇
写道:
鲍勃·格雷斯克(Bob Greschke) * 它与以前的版本相同,除了它"预编译"
struct.unpack()格式字符串. *它的工作类似于Python的方式
处理正则表达式.
我不知道结构课.挺整洁的.太神奇了
这个没有Psyco的版本与Psyco的快速鲍勃版本一样!添加
psyco t o虽然使它 *慢 *,但不会更快.所以这就是我的方式
写它(如果我想要或不得不留在纯python中):
尝试:导入Psyco
除非Inflterror:
从结构导入结构
uncack_i32be = struct("> l").拆开包装
def from3bytes(s):
返回unpack_i32be(s +" \ 0")[0]> 8
别的:
def from3bytes(s):
value =(ord(s [0])<< 16) +(ord(s [1])<< 8) + ord(s [2])
如果值> = 0x800000:
值 - = 0x1000000
返回值
psyco.bind(来自3个Bytes)
hth,
乔治
# 回答17


Ross Ridge George Sakkis 不幸的是,它似乎没有在Python 2.5手册中记录.
速度提高主要来自避免在
包裹结构类的结构模块.结构模块缓存
已经编译了格式字符串,但是在高速缓存中查看格式字符串
在我的原始示例中,结束了很多时间.
罗斯·里奇
- -
l/ //罗斯·里奇(Ross Ridge) - 伟大的HTMU
[oo] [oo] rrxplub.uwaterloo.ca
- () - /()/http://www.csclub.uwaterloo.ca/~rridge/
D b //
# 回答18


罗斯·里奇(Ross Ridge)写道:
George Sakkis 不幸的是,它似乎没有在Python 2.5手册中记录.
在我看来,它已记录为:http://docs.python.org/lib/struct-objects.html
结构模块文档页面
(http://docs.python.org/lib/module-sonstruct.html)提供链接,但没有
明确提及其文本中的结构类.
# 回答19


鲍勃·格雷斯克(Bob Greschke)写道:对不起,正确的代码应为:pyObject* from3bytes(pyObject* self,pyobject* args){const char* s; int len;如果(!pyarg_parsetuple(args," s#",&s&len))返回null;长n =((((((unsigned char)s [0]))<< 16)|(((((unsigned char)s [1]))<< 8)|(((unsigned char)s [2])); if(n> = 0x800000)n- = 0x1000000;返回pyint_fromlong(n);}

不,谢谢.能够更改和安装这些程序
他们安装的计算机比速度更重要.我去了
几年前,沿着C延伸道路变成了一团糟.
一切都必须在太阳,Mac,Linux和Windows上运行
大气术馆如果必须更改.我无法恢复一切
需要重建该程序以外安装Python和
TKINTER(以及一些程序的Pyserial和PIL),他们
需要运行.因此,没有编译,所有内容都在一个文件中,以防万一
新版本必须由用户通过电子邮件发送给他们来升级
他们坐在西藏的一些山上.只是解压缩,粘贴.py
在逻辑上(通常)双击的地方,它们正在关闭并运行.
鲍勃
只是为了娱乐,这是一种使用PIL转换大量3字节整数的方法:
从PIL导入图像
导入数组
def int3_pil(s,trafo =" \ x00"*128+" \ xff"*128):
n = len(s)// 3
im = image.new(" rgb",(n,1))
im.fromstring(S)
嗨,中,lo = im.split()
sign = image.new(" l",(n,1))
sign.fromstring(hi.tostring().translate(trafo))
im = image.merge(" rgba",(lo,mid,hi,sign))
一个 = array.array(" i")
A.Fromstring(im.tostring())
返回a.tolist()
不过,不如我希望的那么快.另外,它需要一些工作才能做到
独立于处理器体系结构.
彼得

# 回答20


在20Áðò,04:10,乔治·萨基斯(George Sakkis)<乔治·萨克(George.Sak.
我不知道结构课.挺整洁的.太神奇了
这个没有Psyco的版本与Psyco的快速鲍勃版本一样!添加
psyco虽然使它 *慢 *,但不会更快.所以这就是我的方式
写它(如果我想要或不得不留在纯python中):
尝试:导入Psyco
除非Inflterror:
从结构导入结构
uncack_i32be = struct("> l").拆开包装
def from3bytes(s):
返回unpack_i32be(s +" \ 0")[0]> 8
别的:
def from3bytes(s):
value =(ord(s [0])<< 16) +(ord(s [1])<< 8) + ord(s [2])
如果值> = 0x800000:
值 - = 0x1000000
返回值
psyco.bind(来自3个Bytes)
hth,
乔治
我能够使用Array模块获得更快的纯Python版本:
a = array.array('l',''.join(('\ 0' + s [i:i + 3] for xrange(0,0,
len(s),3)))))
如果sys.byteorder =='Little':
a.byteswap()
它实际上在C级上移动字节.
测试代码:
导入结构
导入数组
导入系统
umpack_i32be = struct.struct.struct("> l").
s =''.join(struct.pack('> i',1234567)[1:]*1000)
def from3bytes_ord(s):
值= []
对于i在Xrange(0,Len(s),3)中:
值=(ord(s [i])<< 16)| (ord(s [i+1])<< 8)| ORD(S [i+2])
如果值> = 0x800000:
值 - = 0x1000000
values.append(value)
返回值
From3Bytes_struct(s)的def:
返回[unpack_i32be(s [i:i + 3] +" \ 0")[0]> 8 for i in xrange(0,0,
Len(S),3)]
From3Bytes_Array(S)的def:
a = array.array('l',''.join(('\ 0' + s [i:i + 3] for xrange(0,0,
len(s),3)))))
如果sys.byteorder =='Little':
a.byteswap()
返回a.tolist()
从TimeIt导入计时器
t1 = timer(" from3bytes_ord(s)",__ -main __ import s,
从3bytes_ord")
t2 = timer(" from3bytes_struct(s)",__ -main __ import s,
从3Bytes_struct")
t3 = timer("从3bytes_array(s)",__ -main __ import s,
从3bytes_array")
打印'ORD:\ t',T1.TimeIt(1000)
打印'struct:\ t',t2.TimeIt(1000)
打印"数组:\ t',T3.TimeIt(1000)
输出:
ORD:7.08213110884
结构:3.7689164405
数组:2.62995268952
灵感来自Guido的论文http://www.python.org/doc/essays/list2str/
# 回答21


在22ð°ð¿儿时,00:10,Ivan Illarionov 写道:
我能够使用Array模块获得更快的纯Python版本:
a = array.array('l',''.join(('\ 0' + s [i:i + 3] for xrange(0,0,
len(s),3)))))
如果sys.byteorder =='Little':
a.byteswap()
它实际上在C级上移动字节.
测试代码:
导入结构
导入数组
导入系统
umpack_i32be = struct.struct.struct("> l").
s =''.join(struct.pack('> i',1234567)[1:]*1000)
def from3bytes_ord(s):
值= []
对于i在Xrange(0,Len(s),3)中:
值=(ord(s [i])<< 16)| (ord(s [i+1])<< 8)| ORD(S [i+2])
如果值> = 0x800000:
值 - = 0x1000000
values.append(va lue)
返回值
From3Bytes_struct(s)的def:
返回[unpack_i32be(s [i:i + 3] +" \ 0")[0]> 8 for i in xrange(0,0,
Len(S),3)]
From3Bytes_Array(S)的def:
a = array.array('l',''.join(('\ 0' + s [i:i + 3] for xrange(0,0,
len(s),3)))))
如果sys.byteorder =='Little':
a.byteswap()
返回a.tolist()
从TimeIt导入计时器
t1 = timer(" from3bytes_ord(s)",__ -main __ import s,
从3bytes_ord")
t2 = timer(" from3bytes_struct(s)",__ -main __ import s,
从3Bytes_struct")
t3 = timer("从3bytes_array(s)",__ -main __ import s,
从3bytes_array")
打印'ORD:\ t',T1.TimeIt(1000)
打印'struct:\ t',t2.TimeIt(1000)
打印"数组:\ t',T3.TimeIt(1000)
输出:
ORD:7.08213110884
结构:3.7689164405
数组:2.62995268952
受Guido的EssayHttp://www.python.org/doc/essays/list2str/启发
甚至更快:
a = array.array('i','\ 0' +'\ 0'.join((s [i:i:i + 3] for xrange(0,0,
len(s),3)))))
如果sys.byteorder =='Little':
a.byteswap()
我认为这是纯Python中最快的实现
# 回答22


伊万·伊拉里奥诺夫(Ivan Illarionov)写道:
聪明,但请注意,对于负数,它无法正常工作.为了
那些您必须预先准备" \ xff"而不是" \ 0".
彼得
# 回答23


在2008-04-21 14:50:13 -0600,Ivan Illarionov 死记硬背:
我能够使用数组模块获得更快的纯python版本:a = array.array('l',''.join(('\ 0' + s [i:i + 3] for xrange(0) ,len(s), 3))))if sys.byteorder == 'little':a.byteswap()It actually moves bytes around on C level.test code:import structimport arrayimport sysunpack_i32be = struct.Struct(">l ").unpacks =''.join(struct.pack('> i',1234567)[1:]*1000)def from3bytes_ord(s):in xrange(0,len(s), 3):value =(ord(s [i])<< 16)| (ord(s [i+1])<< 8)| ord(s [i+2])如果值> = = 0x800000:value- = 0x10000000000values.append(value)return valuesdef从3bytes_struct(s):return [unpack_i32be(s [i:i+3] 0]> 8在Xrange(0,len(s),3)] def from3Bytes_Array(s):a = array.Array('l','.join((('\ 0' + s [i:i:':: i+3]对于i在Xrange中的i(0,len(s),3),))))如果sys.byteorder =='little':a.byteswap()return a.tolist()timeit import import import timert timert1 = timer("从__main __ import s,从3bytes_ord")t2 = timer(" from3bytes_struct(s)",从__ -main __ import s,从__ -main __ s,来自3Bytes_array")打印'ORD:\ t',t1.timeit(1000)打印'struct:\ t',t2.timeit(1000)打印'数组:\ t',t3.timeit(1000)输出:Ord off:ORD:ORD :7.082131108884结构:3.7689164405Array:2.62995268952由Guido的EssayHttp://www.python.org/doc/doc/essays/list2ststr/ insed

甚至更快:
a = array.array('i','\ 0' +'\ 0'.join((s [i:i:i + 3] for xrange(0,0,
len(s),3)))))
如果sys.byteorder =='Little':
a.byteswap()
我认为这是纯Python中最快的实现
酸! :)结构如何变得如此快?我猜已经有
自2.3以来的改进(这是我一直在研究的).我要去
能够回到我的IBM P C XT即将很快. :)
谢谢!

# 回答24


鲍勃·格雷斯克(Bob Greschke)写道:
死记硬背:
甚至更快:a = array.array('i','\ 0' +'\ 0'.join((s [i:i:i + 3] for xrange(0,len(s),3)) ))如果sys.byteorder =='little':a.byteswap()我认为这是纯Python中最快的实现

酸! :)结构如何变得如此快?我猜已经有
自2.3以来的改进(这是我一直在研究的).我要去
为了能够很快回到我的IBM PC XT. :)
谢谢!
是的,鲍勃·伊波利托(Bob Ippolito)花了很多时间来改善它的需求
2.4(?)发布前不久的速度冲刺.表明.
问候
史蒂夫
- -
史蒂夫·霍顿+1 571 484 6266 +1 800 494 3119
Holden Web LLC http://www.holdenweb.com/

# 回答25


在22Áðò,01:01,彼得·奥特(Peter Otten)<__ pete ...@web.dewrote:
聪明,但请注意,对于负数,它无法正常工作.为了
那些您必须预先准备" \ xff"而不是" \ 0".
彼得
感谢您的更正.
需要另一个步骤:
a = array.array('i','\ 0' +'\ 0'.join((s [i:i:i + 3] for xrange(0,0,
len(s),3)))))
如果sys.byteorder =='Little':
a.byteswap()
结果= [n如果n <0x800000 else n -0x1000000 for a]
而且它仍然很快:)
# 回答26


有些东西是腥的.我只是跑了这个思想简单的东西,我,
同样,为ORD()获得比我在a上的unwack()更好的时间
2.8GHz OSX iMac,具有2.5.1.这是您可以多次的迭代
使用您的手表方法:
------
#! /usr/bin/env Python
从OS导入系统
从struct导入打开包装
打印"拆包1"
系统("日期")
对于Xrange(0,100000000)中的X:
值=拆卸("> b"," a")
系统("日期")
打印
打印" ORD 1"
系统("日期")
对于Xrange(0,100000000)中的X:
值= ORD(" A")
系统("日期")
打印
打印"打开3"
系统("日期")
对于Xrange(0,100000000)中的X:
值=打开包装("> bbb"," ABC")
系统("日期")
打印
打印" ORD 3"
系统("日期")
对于Xrange(0,100000000)中的X:
value =(ord(" a")<< 16)+(ord(" b")<< 8)+ord(" c")
系统("日期")
------
拆箱1大约是1M20
ORD 1大约20秒
打开3个大约是1M20
ORD 3约为1M03S
平均几次.
# 回答27


在2008-04-21 16:51:13 -0600,Bob Greschke 只是完全忽略了最后一个.真是个浓汤.这里:
#! /usr/bin/env Python
从OS导入系统
从struct导入打开包装
打印"拆包1"
系统("日期")
对于Xrange(0,100000000)中的X:
value = unwack("> b"," a")[0]
如果值0x800000:
值 - = 0x1000000
系统("日期")
打印
打印" ORD 1"
系统("日期")
对于Xrange(0,100000000)中的X:
值= ORD(" A")
如果值0x800000:
值 - = 0x1000000
系统("日期")
打印
打印"打开3"
系统("日期")
对于Xrange(0,100000000)中的X:
value1,value2,value3 = uncack("> bbb"," abc")
value =(value1 << 16)+(value2 << 8)+value3
如果值0x800000:
值 - = 0x1000000
系统("日期")
打印
打印" ORD 3"
系统("日期")
对于Xrange(0,100000000)中的X:
value =(ord(" a")<< 16)+(ord(" b")<< 8)+ord(" c")
如果值0x800000:
值 - = 0x100 0000
系统("日期")
尽管如
扔在if的乐趣中).
# 回答28


4月21日,下午5:30,Ivan Illarionov 感谢您的更正.
需要另一个步骤:
a = array.array('i','\ 0' +'\ 0'.join((s [i:i:i + 3] for xrange(0,0,
len(s),3)))))
如果sys.byteorder =='Little':
a.byteswap()
结果= [n如果n <0x800000 else n -0x1000000 for a]
而且它仍然很快:)
确实,阵列的想法是为大量投入带回报.在我的盒子上
(Python 2.5,Winxp,2GHz Intel Core Duo),截止点
从3bytes_array开始比3ByTes_struct接近150
数字(= 450个字节).
尽管Psyco现在几乎是结构解决方案的两倍
启用,虽然数组无法从中受益.这里有一些
样本运行中的数字:
***没有psyco ***
尺寸= 1
从3bytes_ord:0.033493
从3Bytes_struct:0.018420
从3ByTes_Array:0.089735
尺寸= 10
从3bytes_ord:0.140470
从3Bytes_struct:0.082326
从3ByTes_Array:0.142459
尺寸= 100
从3Bytes_ord:1.180831
从3Bytes_struct:0.664799
从3ByTes_Array:0.690315
尺寸= 1000
从3bytes_ord:11.551990
从3ByTes_struct:6.390999
从3ByTes_Array:5.781636
***与psyco ***
尺寸= 1
从3bytes_ord:0.039287
从3Bytes_struct:0.009453
从3ByTes_Array:0.098512
尺寸= 10
从3bytes_ord:0.174362
从3Bytes_struct:0.045785
从3ByTes_Array:0.162171
尺寸= 100
从3bytes_ord:1.437203
从3Bytes_struct:0.355930
从3ByTes_Array:0.800527
尺寸= 1000
从3bytes_ord:14.248668
从3ByTes_struct:3.331309
从3ByTes_Array:6.946709
这是基准脚本:
导入结构
从数组导入数组
def from3bytes_ord(s):
返回[n如果n <0x800000 else n-0x1000000 for n in
((ord(s [i])<< 16)|(ord(s [i+1])<< 8)| ord(s [i+2])
对于i在Xrange(0,Len(s),3))]]]
umpack_i32be = struct.struct.struct('> l').
From3Bytes_struct(s)的def:
返回[unpack_i32be(s [i:i + 3] +'\ 0')[0] >> 8
对于i在Xrange(0,Len(s),3)]
From3Bytes_Array(S)的def:
a = array('l',''.join('\ 0' + s [i:i + 3]
对于i在Xrange(0,len(s),3)))))))
a.byteswap()
返回[n如果n <0x800000 else n-0x1000000 for a]
DEF基准测试():
从TimeIt导入计时器
对于1,10,100,1000中的n:
打印'size =%d'%n
#正面和负面之间的循环
buf =''.join(struct.pack('> i',1234567*( - 1)**(i%2))[1:]
因为我在Xrange(n)中)
对于" from3bytes_ord"中的func,'从3bytes_struct',
'来自3bytes_array':
打印'%s:%f'%(func,
计时器('%s(buf)'%func,
'来自__ -main __进口%s; buf =%r'%(func,buf)
).TimeIT(10000))
如果__name__ =='__ main __':
s =''.join(struct.pack('> i',v)[1:]
[0,1,-2,500,-500,7777,-7777,-94496,98765,
-98765,838607,-8388607,-8388608,1234567]))
从3bytes_ord(s)== From3Bytes_struct(s)==
来自3Bytes_Array(S)
打印'***无PSYCO ***'
基准()
进口psyco; psyco.full()
打印'***与psyco ***'
基准()
乔治
# 回答29


在2008-04-21 17:06:39 -0600,Bob Greschke 我只是在我的 2.3.4和
打开1:7m53s
ORD 1:2M00
打开3:14m20s
ORD 3:5M30
时间表看上去以某种方式打破了我.
# 回答30


乔治·萨基斯(George Sakkis)在2008年4月21日星期一16:10:05 -0700写道:谢谢您的更正. s [i:i+3] for i in xrange(0,len(s),3)))))如果sys.byteorder =='little':a.byteswap()result = [n如果n <0x800000 -n]中的n个0x1000000,它仍然很快:)

确实,阵列的想法是为大量投入带回报.在我的盒子上
(Python 2.5,Winxp,2GHz Intel Core Duo),截止点
从3bytes_array开始比3ByTes_struct接近150
数字(= 450个字节).
尽管Psyco现在几乎是结构解决方案的两倍
启用,虽然数组无法从中受益.这是一些数字
从样本运行中:
***没有psyco ***
尺寸= 1
从3bytes_ord:0.033493
从3Bytes_struct:0.018420
从3ByTes_Array:0.089735
尺寸= 10
从3bytes_ord:0.140470
从3Bytes_struct:0.082326
从3ByTes_Array:0.142459
尺寸= 100
从3Bytes_ord:1.180831
从3Bytes_struct:0.664799
从3ByTes_Array:0.690315
尺寸= 1000
从3bytes_ord:11.551990
从3ByTes_struct:6.390999
从3ByTes_Array:5.781636
***与psyco ***
尺寸= 1
从3bytes_ord:0.039287
从3Bytes_struct:0.009453
从3ByTes_Array:0.098512
尺寸= 10
从3bytes_ord:0.174362
从3Bytes_struct:0.045785
从3ByTes_Array:0.162171
尺寸= 100
从3bytes_ord:1.437203
从3Bytes_struct:0.355930
从3ByTes_Array:0.800527
尺寸= 1000
从3bytes_ord:14.248668
从3ByTes_struct:3.331309
从3ByTes_Array:6.946709
这是基准脚本:
导入结构
从数组导入数组
def from3bytes_ord(s):
返回[n如果n <0x800000 else n-0x1000000 for n in
((ord(s [i])<< 16)|(ord(s [i+1])<< 8)| ord(s [i+2])
对于i在Xrange(0,Len(s),3))]]]
umpack_i32be = struct.struct.struct('> l').从3bytes_struct(s)的uncack def(s):
返回[unpack_i32be(s [i:i + 3] +'\ 0')[0] >> 8
对于i在Xrange(0,Len(s),3)]
From3Bytes_Array(S)的def:
a = array('l',''.join('\ 0' + s [i:i + 3]
对于i在Xrange(0,len(s),3)))))))
a.byteswap()
返回[n如果n <0x800000 else n-0x1000000 for a]
DEF基准测试():
从TimeIt导入计时器
对于1,10,100,1000中的n:
打印'size =%d'%n
#正面和负buf之间的循环=
''.join(struct.pack('> i',1234567*( - 1)**(i%2))[1:]
因为我在Xrange(n)中)
对于" from3bytes_ord"中的func,'从3bytes_struct',
'来自3bytes_array':
打印'%s:%f'%(func,
计时器('%s(buf)'%func,
'来自__ -main __进口%s; buf =%r'%(func,buf)
).TimeIT(10000))
如果__name__ =='__ main __':
s =''.join(struct.pack('> i',v)[1:]
[0,1,-2,500,-500,7777,-7777,-94496,98765, -98765,838607,-8388607,-8388608,1234567]))
从3bytes_ord(s)== From3Bytes_struct(s)==
来自3Bytes_Array(S)
打印'***无PSYCO ***'
基准()
进口psyco; psyco.full()
打印'***与psyco ***'
基准()
乔治
注释:
您没有使用更快的阵列方法:
''.join('\ 0' + s [i:i + 3] for xrange(0,len(s),3))
比慢
'\ 0' +'\ 0'.join(s [i:i + 3] for xrange(0,len(s),3))
鲍勃·格雷斯克(Bob Greschke):
结构在带有struct.struct类别的Python 2.5中很快.
阵列方法应适用于Python 2.3,可能是最快的
一个(没有psyco)有大量输入:
From3Bytes_Array(S)的def:
a = array.array('i','\ 0' +'\ 0'.join([s [i:i + 3]
对于i在Xrange(0,Len(s),3)])))))))
a.byteswap()#如果您的系统是LITLE-ENDIAN
返回[n> = 0x800000和n -0x1000000或n]
- -
伊万

# 回答31


乔治·萨基斯(George Sakkis)在2008年4月21日星期一16:10:05 -0700写道:谢谢您的更正. s [i:i+3] for i in xrange(0,len(s),3)))))如果sys.byteorder =='little':a.byteswap()result = [n如果n <0x800000 -n]中的n个0x1000000,它仍然很快:)

确实,阵列的想法是为大量投入带回报.在我的盒子上
(Python 2.5,Winxp,2GHz Intel Core Duo),截止点
从3bytes_array开始比3ByTes_struct接近150
数字(= 450个字节).
尽管Psyco现在几乎是结构解决方案的两倍
启用,虽然数组无法从中受益.这是一些数字
从样本运行中:
***没有psyco ***
尺寸= 1
从3bytes_ord:0.033493
从3Bytes_struct:0.018420
从3ByTes_Array:0.089735
尺寸= 10
从3bytes_ord:0.140470
从3Bytes_struct:0.082326
从3ByTes_Array:0.142459
尺寸= 100
从3Bytes_ord:1.180831
从3Bytes_struct:0.664799
从3ByTes_Array:0.690315
尺寸= 1000
从3bytes_ord:11.551990
从3ByTes_struct:6.390999
从3ByTes_Array:5.781636
***与psyco ***
尺寸= 1
从3bytes_ord:0.039287
从3Bytes_struct:0.009453
从3ByTes_Array:0.098512
尺寸= 10
从3bytes_ord:0.174362
从3Bytes_struct:0.045785
从3ByTes_Array:0.162171
尺寸= 100
从3bytes_ord:1.437203
从3Bytes_struct:0.355930
从3ByTes_Array:0.800527
尺寸= 1000
从3bytes_ord:14.248668
从3ByTes_struct:3.331309
从3ByTes_Array:6.946709
这是基准脚本:
导入结构
从数组导入数组
def from3bytes_ord(s):
返回[n如果n <0x800000 else n-0x1000000 for n in
((ord(s [i])<< 16)|(ord(s [i+1])<< 8)| ord(s [i+2])
对于i在Xrange(0,Len(s),3))]]]
umpack_i32be = struct.struct.struct('> l').从3bytes_struct(s)的uncack def(s):
返回[unpack_i32be(s [i:i + 3] +'\ 0')[0] >> 8
对于i在Xrange(0,Len(s),3)]
From3Bytes_Array(S)的def:
a = array('l',''.join('\ 0' + s [i:i + 3]
对于i在Xrange(0,len(s),3)))))))
a.byteswap() 返回[n如果n <0x800000 else n-0x1000000 for a]
DEF基准测试():
从TimeIt导入计时器
对于1,10,100,1000中的n:
打印'size =%d'%n
#正面和负buf之间的循环=
''.join(struct.pack('> i',1234567*( - 1)**(i%2))[1:]
因为我在Xrange(n)中)
对于" from3bytes_ord"中的func,'从3bytes_struct',
'来自3bytes_array':
打印'%s:%f'%(func,
计时器('%s(buf)'%func,
'来自__ -main __进口%s; buf =%r'%(func,buf)
).TimeIT(10000))
如果__name__ =='__ main __':
s =''.join(struct.pack('> i',v)[1:]
[0,1,-2,500,-500,7777,-7777,-94496,98765,
-98765,838607,-8388607,-8388608,1234567]))
从3bytes_ord(s)== From3Bytes_struct(s)==
来自3Bytes_Array(S)
打印'***无PSYCO ***'
基准()
进口psyco; psyco.full()
打印'***与psyco ***'
基准()
乔治
注释:
您没有使用更快的阵列方法:
''.join('\ 0' + s [i:i + 3] for xrange(0,len(s),3))
比慢
'\ 0' +'\ 0'.join(s [i:i + 3] for xrange(0,len(s),3))
鲍勃·格雷斯克(Bob Greschke):
结构在带有struct.struct类别的Python 2.5中很快.
阵列方法应适用于Python 2.3,可能是最快的
一个(没有psyco)有大量输入:
From3Bytes_Array(S)的def:
a = array.array('i','\ 0' +'\ 0'.join([s [i:i + 3]
对于i在Xrange(0,Len(s),3)])))))))
a.byteswap()#如果您的系统是LITLE-ENDIAN
返回[n> = 0x800000和n -0x1000000或n]
- -
伊万

# 回答32


4月22日,12:04*上午,Ivan Illarionov
写道:
注释:
您没有使用更快的阵列方法:
''.join('\ 0' + s [i:i + 3] for xrange(0,len(s),3))
比慢
'\ 0' +'\ 0'.join(s [i:i + 3] for xrange(0,len(s),3))
接得好;更快的版本减少了截止点
从3bytes_array和3Bytes_struct到〜50个数字(= 150个字节)
仅(没有psyco).
乔治

标签: python

添加新评论