Pyrex 扩展并加速 Python 应用程序
2007-03-29 12:21:49 来源:WEB开发网剖析
有些东西似乎不对。速度提高几个百分比和 Pyrex 主页(以及很多 Pyrex 用户)那样提高 40 倍有很大的差距。现在应该来看一下这个 Python _mint() 函数中 哪些 地方真正消耗了时间。有一个 quick 脚本(此处没有给出)可以分解复杂操作 sha(challenge+hex(counter)[2:]).hexdigest():
清单 8. hashcash 的 mint 函数的时间消耗1000000 empty loops: 0.559
------------------------------
1000000 sha()s: 2.332
1000000 hex()[2:]s: 3.151
just hex()s: <2.471>
1000000 concatenations: 0.855
1000000 hexdigest()s: 3.742
------------------------------
Total: 10.079
显然,我并不能将这个循环从 _mint() 函数中删除。虽然 Pyrex 改进后的 for 循环可能有一点加速,但是整个函数主要是一个循环。我也不能删除对 sha() 的调用,除非要使用 Pyrex 重新实现 SHA-1(即使我要这样做,也没有自信自己可以比 Python 标准的 sha 模块的作者做得更好)。而且,如果我希望得到一个 sha.SHA 对象的 hash 值,就只能调用 .hexdigest() 或 .digest();前者的速度更快。
现在真正要解决的是 hex() 对 counter 变量的转换,以及结果中时间片的消耗情况。我可能需要使用 Pyrex/C 的字符串连接操作,而不是 Python 的字符串对象。然而,我见过的惟一一种避免 hex() 转换的方法是手工在嵌套循环之外构建一个后缀。虽然这样做可以避免 int 到 char 类型的转换,但是需要生成更多代码:
清单 9. 完全 Pyrex 优化过的 mint 函数cdef _mint(char *challenge, int bits):
cdef int hex_digits, i0, i1, i2, i3, i4, i5
cdef char *ab, *digest, *trial, *suffix
suffix = '******'
ab = alphabet
hex_digits = int(ceil(bits/4.))
hash = sha
for i0 from 0 <= i0 < 55:
suffix[0] = ab[i0]
for i1 from 0 <= i1 < 55:
suffix[1] = ab[i1]
for i2 from 0 <= i2 < 55:
suffix[2] = ab[i2]
for i3 from 0 <= i3 < 55:
suffix[3] = ab[i3]
for i4 from 0 <= i4 < 55:
suffix[4] = ab[i4]
for i5 from 0 <= i5 < 55:
suffix[5] = ab[i5]
py_digest = hash(challenge+suffix).hexdigest()
digest = py_digest
for i from 0 <= i < hex_digits:
if digest[i] != c'0': break
else:
return suffix
- ››扩展Axis2框架,支持基于JVM的脚本语言
- ››扩展WebSphere Portal V6个性化功能
- ››扩展JavaScript的时候,千万要保留其原来的所有功...
- ››扩展数据:如何为 Model 750 服务器选择 I/O 扩展...
- ››扩展 JDT 实现自动代码注释与格式化
- ››扩展 secldap 的功能以验证多个数据源
- ››扩展 JUnit4 以促进测试驱动开发
- ››加速点播 迅雷XMP全面提升在线视频播放速度
- ››扩展 JUnit 测试并行程序
- ››扩展的ToolStripEx控件
- ››扩展 Eclipse 的 Java 开发工具
- ››扩展 Eclipse 辅助和规范开发流程
更多精彩
赞助商链接