我正在使用以下代码与数字万用表(DMM)通信。
它工作正常。我可以发送命令并读取结果。 我不使用readline,因为我读取的是二进制数据。 问题: 问题在于它非常非常慢。 用Ruby编写的相同代码要快得多。 当Python需要30秒时,Ruby只需要2或3秒(使用相同的速度)。 所以这不是硬件问题。
Ruby代码和Python之间唯一的区别是,在Python中,我使用inWaiting()来读取所有可用字符。在Ruby中,read()函数读取所有字符而不仅仅是一个。 代码: 以下是代码: 在read_retry函数中,我检查需要读取多少个字符。 然后我读取它们,并调用data_is_ok函数检查是否已完成。
正如你所看到的,返回的数据中嵌入了“\r”。 当最后一个字符是“\r”时(没有更多数据可用),读取就完成了。
因此,有一个循环来读取许多块。
问题:
能否使代码更快?
它工作正常。我可以发送命令并读取结果。 我不使用readline,因为我读取的是二进制数据。 问题: 问题在于它非常非常慢。 用Ruby编写的相同代码要快得多。 当Python需要30秒时,Ruby只需要2或3秒(使用相同的速度)。 所以这不是硬件问题。
Ruby代码和Python之间唯一的区别是,在Python中,我使用inWaiting()来读取所有可用字符。在Ruby中,read()函数读取所有字符而不仅仅是一个。 代码: 以下是代码: 在read_retry函数中,我检查需要读取多少个字符。 然后我读取它们,并调用data_is_ok函数检查是否已完成。
正如你所看到的,返回的数据中嵌入了“\r”。 当最后一个字符是“\r”时(没有更多数据可用),读取就完成了。
因此,有一个循环来读取许多块。
import serial
[...]
def data_is_ok(data):
# No status code yet
if len(data) < 2: return False
# Non-OK status
if len(data) == 2 and data[0] != "0" and data[1] == "\r": return True
# Non-OK status with extra data on end
if len(data) > 2 and data[0] != "0":
raise ValueError('Error parsing status from meter (Non-OK status with extra data on end)')
# We should now be in OK state
if data[0] != "0" or data[1] != "\r":
raise ValueError('Error parsing status from meter (status:%c size:%d)' % (data[0], len(data)))
return len(data) >= 4 and data[-1] == "\r"
def read_retry():
retry_count = 0
data = ""
while retry_count < 500 and not data_is_ok(data):
bytesToRead = ser.inWaiting()
data += ser.read(bytesToRead)
if data_is_ok(data): return data
time.sleep (0.001)
retry_count += 1
raise ValueError('Error parsing status from meter: %c %d %r %r' % (data[0],len(data),data[1] == '\r', data[-1] == '\r'))
[...]
# Serial port settings
try:
ser = serial.Serial(port='/dev/cu.usbserial-AK05FTGH', baudrate=115200, bytesize=8, parity='N', stopbits=1, timeout=5, rtscts=False, dsrdtr=False)
except serial.serialutil.SerialException, err:
print "Serial Port /dev/cu.usbserial-AK05FTGH doesn't respond"
print err
sys.exit()
[...]
ser.write(cmd+'\r')
data = read_retry()
我使用了cProfile分析器。大部分时间都花在了time.sleep上。
以下是摘录:
363096 function calls (363085 primitive calls) in 28.821 seconds
Ordered by: internal time
List reduced from 127 to 10 due to restriction <10>
ncalls tottime percall cumtime percall filename:lineno(function)
19050 25.245 0.001 25.245 0.001 {time.sleep}
1 1.502 1.502 1.502 1.502 {posix.open}
问题:
能否使代码更快?