我正在尝试使用Beaglebone Black(BBB)和Python制作传感器。我需要从传感器每秒获得尽可能多的数据。下面的代码允许我每秒收集大约100,000个数据点。
import Adafruit_BBIO_GPIO as GPIO
import time
GPIO.setup("P8_13", GPIO.IN)
def get_data(n):
my_list = []
start_time = time.time()
for i in range(n):
my_list.append(GPIO.input("P8_13"))
end_time = time.time() - start_time
print "Time: {}".format(end-time)
return my_list
n = 100000
get_data(n)
如果n = 1,000,000,填充my_list大约需要10秒,当n = 100,000且time = 1s时,这个速率相同。
我决定尝试使用Cython来获得更好的效果。我听说它可以显着加快python代码。我按照基本的Cython教程:使用上面的python代码创建了data.pyx文件,然后创建了一个setup.py,最后构建了Cython文件。
不幸的是,这根本没有帮助我。所以,我想知道我是否使用Cython不当或在这种情况下,当没有"繁重的数学计算"时,Cython不能帮助太多。任何关于如何加速我的代码的建议都非常感谢!
答案 0 :(得分:2)
您可以从添加静态类型声明开始:
import Adafruit_BBIO_GPIO as GPIO
import time
GPIO.setup("P8_13", GPIO.IN)
def get_data(int n): # declared as an int
my_list = []
start_time = time.time()
for i in range(n):
my_list.append(GPIO.input("P8_13"))
end_time = time.time() - start_time
print "Time: {}".format(end-time)
return my_list
n = 100000
get_data(n)
这允许循环本身转换为纯C循环,缺点是n
不再是任意精度(所以如果你试图传递一个大于20亿的值,你会得到未定义的行为)。将int
更改为unsigned long long
可以减轻此问题,unsigned
允许的值最高为2 ** 64 - 1,或大约为18 quintillion。 {{1}}量词表示您无法传递负值。
如果您可以删除列表,您将获得更大幅度的提升速度。尝试用array
替换它。 Cython可以work more efficiently with arrays than with lists。
答案 1 :(得分:0)
我尝试了相同的代码,但使用了不同版本的Adafruit_BBIO, 在我的rev C板上运行一百万次只需要3秒钟。
我认为从Rev B到Rev C的主板变化是eMMC从2GB增加到4GB。
如果您去获取当前的Adafruit_BBIO,您在上面的代码中需要更改的是第一个导入语句,它应该是Adafruit_BBIO.GPIO as GPIO
你接下来尝试了什么?
罗恩