def sieve(n):
nums = [0] * n
for i in range(2, int(n**0.5)+1):
if nums[i] == 0:
for j in range(i*i, n, i):
nums[j] = 1
return [i for i in range(2, n) if nums[i] == 0]
def sieve_var(n):
nums = [0] * n
for i in range(3, int(n**0.5)+1, 2):
if nums[i] == 0:
for j in range(i*i, n, i):
nums[j] = 1
return [2] + [i for i in range(3, n, 2) if nums[i] == 0]
Run Code Online (Sandbox Code Playgroud)
在我的机器上,sieve(10**8)
需要2.28秒,而sieve_var(10**8) …
通常声称RPython(Python的一个子集)是静态类型的.(例如在维基百科上.)
最初,我想知道他们如何将它添加到Python并认为他们可能已经添加了添加语句的要求,例如assert isinstance(arg1, ...)
在每个函数的开头(但我真的不相信).
然后我查看了一些RPython代码,它看起来并没有真正的静态类型.在许多情况下,可能是编译器可以证明函数参数只能是某些类型,但绝对不是在所有情况下.
例如,这是RPython的实现string.split
:
def split(value, by, maxsplit=-1):
bylen = len(by)
if bylen == 0:
raise ValueError("empty separator")
res = []
start = 0
while maxsplit != 0:
next = value.find(by, start)
if next < 0:
break
res.append(value[start:next])
start = next + bylen
maxsplit -= 1 # NB. if it's already < 0, it stays < 0
res.append(value[start:len(value)])
return res
Run Code Online (Sandbox Code Playgroud)
在关于RPython的PyPy文档中,有人说:" 变量应该包含最多一种类型的值 ".
那么,函数参数也算作变量吗?或者在什么意义上RPython静态输入?或者这实际上是错误的?
我一直在玩python中编写cffi模块,他们的速度让我想知道我是否正确使用标准python.这让我想彻底切换到C!说实话,有一些伟大的python库我永远无法在C中重新实现自己,所以这比任何事情都更加假设.
这个例子显示了python中的sum函数与numpy数组一起使用,以及与ac函数相比有多慢.是否有更快的pythonic方法来计算numpy数组的总和?
def cast_matrix(matrix, ffi):
ap = ffi.new("double* [%d]" % (matrix.shape[0]))
ptr = ffi.cast("double *", matrix.ctypes.data)
for i in range(matrix.shape[0]):
ap[i] = ptr + i*matrix.shape[1]
return ap
ffi = FFI()
ffi.cdef("""
double sum(double**, int, int);
""")
C = ffi.verify("""
double sum(double** matrix,int x, int y){
int i, j;
double sum = 0.0;
for (i=0; i<x; i++){
for (j=0; j<y; j++){
sum = sum + matrix[i][j];
}
}
return(sum);
}
""")
m = np.ones(shape=(10,10))
print 'numpy says', m.sum()
m_p = cast_matrix(m, …
Run Code Online (Sandbox Code Playgroud) 我们有一大堆python代码,它们需要一些输入并产生一些输出.
我们希望保证,在相同输入的情况下,无论python版本还是本地环境,我们都会生成相同的输出.(例如代码是在Windows,Mac还是Linux上运行,32位或64位)
我们已经在自动化测试套件中执行了这个操作,通过运行我们的程序,无论是否有-R
python选项和比较输出,假设这会消除我们的输出意外结束的任何位置依赖于迭代超过a dict
.(我们的代码中最常见的非确定性来源)
但是,由于我们最近调整了代码以支持python 3,我们发现了一个地方,我们的输出部分依赖于dict
使用int
s作为键的迭代.与python2相比,这个迭代顺序在python3中发生了变化,并使我们的输出变得不同.我们现有的测试(全部在python 2.7上)没有注意到这一点.(因为-R
不影响int
s 的哈希)一旦找到,它很容易修复,但我们希望早点找到它.
是否有任何方法可以进一步对我们的代码进行压力测试,并让我们相信我们已经根据python版本/环境可能会有所不同的内容隐瞒了我们最终隐藏的所有地方?我认为,类似-R
或者PYTHONHASHSEED
是应用于数字以及为str
,bytes
,和datetime
对象可以工作,但我开到其他的方法.但是,如果可能的话,我希望我们的自动测试机只需要安装一个python版本.
另一个可接受的替代方案是使用pypy调整运行我们的代码的某种方式,以便在迭代项目时使用不同的顺序dict
; 我认为我们的代码是在pypy上运行的,尽管它不是我们曾经明确支持过的东西.但是,如果一些pypy专家为我们提供了一种在不同的运行中调整字典迭代顺序的方法,那么我们将努力实现这一目标.
只是一个简单的问题,我如何让pypy识别我在Python中使用的第三个pary模块?例如,我收到以下错误.
from tables import *
ImportError: No Module named tables
Run Code Online (Sandbox Code Playgroud)
这基本上是说它无法找到我用来与我试图运行的脚本进行交互的pytables库.
这是项目欧拉问题49的一个(略微混乱)尝试.
我应该直截了当地说这deque
不是一个好选择!我的想法是缩小质数集来测试成员资格会导致循环加速.然而,当我意识到我应该使用a set
(并且不用担心删除元素)时,我的速度提高了60倍.
from collections import deque
from itertools import permutations
from .sieve import sieve_of_erastothenes # my own implementation of the Sieve of Erastothenes
primes = deque(prime for prime in sieve_of_erastothenes(10000) if prime > 1000 and prime != 1487) # all four-digit primes except 1487
try:
while True:
prime = primes.popleft() # decrease the length of primes each time to speed up membership test
for inc in xrange(1,10000 + 1 - (2 * prime)): # …
Run Code Online (Sandbox Code Playgroud) 我被告知你可以使用PyPy来运行Python程序,因为它是使用JIT编译器编译而不是解释而快得多.
以下程序找到数字600851475143的最大素数因子:
import numpy as np
nr = 600851475143
n = 2
while n <= np.sqrt(nr):
if nr%n == 0:
nr = nr/n
n += 1
print(nr)
Run Code Online (Sandbox Code Playgroud)
使用PyPy运行它的程序是什么?
我知道他们的网站上有文档,但我不明白,并希望进行演示.
PyPy GIL是RPython中PyPy解释器实现的一部分,还是translate.py自动添加的东西?也就是说,如果我要在RPython中编写我自己的新语言解释器并通过translate.py运行它,它是否会先于GIL,或者是由我的解释器代码决定的?
我想弄清楚1984年3月16日有什么特别之处.在我使用的虚拟机上(没有什么特别之处),Python(以及PyPy)在尝试使用mktime时崩溃了,这似乎是一个非常合理的时间结构.
$ pypy
Python 2.7.3 (f66246c46ca30b26a5c73e4cc95dd6235c966b8f, Jul 30 2013, 09:27:06)
[PyPy 2.0.2 with GCC 4.4.7 20120313 (Red Hat 4.4.7-3)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>>> import time
>>>> time.mktime((1984,3,16,0,0,0,0,0,0))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
OverflowError: mktime argument out of range
>>>> time.mktime((1984,3,15,0,0,0,0,0,0))
448156800.0
>>>> time.mktime((1984,3,17,0,0,0,0,0,0))
448326000.0
>>>> time.mktime((1984,3,16,0,0,0,0,0,0))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
OverflowError: mktime argument out of range
>>>> …
Run Code Online (Sandbox Code Playgroud) pypy ×10
python ×8
rpython ×2
c ×1
deque ×1
gil ×1
mktime ×1
numpy ×1
performance ×1
pytables ×1
python-2.7 ×1
python-3.x ×1
python-cffi ×1
timezone ×1