Desempenho inconsistente de Python no Windows
Eu tenho algum código Python 2.7 no qual estou trabalhando e funciona muito bem em qualquer sistema do tipo * nix. No entanto, no Windows, a mesma seção do código terá tempos de execução muito diferentes. Observe minha saída de depuração abaixo. t é o tempo total de cada passagem, s é o tempo para gerar os dados e u é o tempo para enviar esses dados em série para o meu dispositivo (todos em milissegundos).
t: 9 - s: 3 - u: 6
t: 14 - s: 9 - u: 5
t: 9 - s: 3 - u: 6
t: 9 - s: 3 - u: 6
t: 15 - s: 8 - u: 7
t: 14 - s: 9 - u: 5
t: 11 - s: 5 - u: 6
t: 15 - s: 9 - u: 6
t: 14 - s: 9 - u: 5
t: 13 - s: 8 - u: 5
t: 15 - s: 9 - u: 6
t: 15 - s: 9 - u: 6
t: 14 - s: 8 - u: 6
t: 11 - s: 6 - u: 5
t: 11 - s: 5 - u: 6
t: 15 - s: 8 - u: 7
t: 15 - s: 10 - u: 5
t: 7 - s: 2 - u: 5
t: 15 - s: 9 - u: 6
t: 15 - s: 9 - u: 6
t: 13 - s: 7 - u: 6
t: 12 - s: 7 - u: 5
t: 12 - s: 6 - u: 6
t: 15 - s: 9 - u: 6
t: 8 - s: 2 - u: 6
t: 14 - s: 9 - u: 5
t: 15 - s: 9 - u: 6
t: 14 - s: 9 - u: 5
t: 15 - s: 9 - u: 6
t: 14 - s: 8 - u: 6
t: 14 - s: 9 - u: 5
t: 14 - s: 9 - u: 5
t: 9 - s: 4 - u: 5
t: 11 - s: 5 - u: 6
O tempo de envio serial não é um problema e geralmente muito consistente. É a etapa "s", na qual ele gera os dados problemáticos, levando de 2 a 9 milissegundos. Bastante um balanço enorme! No Debian (rodando em um raspberry pi par), essa parte leva 11-12 ms muito consistentes.
Há muitos outros códigos em torno disso, mas a etapa indicada pelo tempo "s" é basicamente esta:
buf = [wheel_helper(self._vector[y][x], h, s) for y in range(h) for x in range(w)]
buf = [i for sub in buf for i in sub]
self._led.setBuffer(buf)
Ele gera um padrão de arco-íris em uma matriz em que a cor se baseia na distância do centro. Mas isso étudo que fazcada Tempo. Não vejo razão para variar tão descontroladamente no tempo.
Alguma ideia?
Atualizar: Você geralmente pode ignorar o código que estou executando na etapa "s". Este é apenas um exemplo demuitos, todos executados em um período de tempo muito variável. Alguns estão usando o alcance, outros não. Está em toda parte, mas sempre é um problema.
Atualização 2:
Ok, eu fiz alguns testes adicionais e fiz um exemplo que é muito simples enão use range! Calcula os 1000 primeiros elementos da sequência de fibonacci 1000 vezes. Muito simples, certo? Porém, no Windows, a diferença entre a execução mais rápida e a mais lenta seria quase 375% mais longa (Max / Min na saída de exemplo abaixo). Todos os valores de tempo são milissegundos.
import time
import math
min = 10
max = 0
avg = 0
sum = 0
count = 0
def msec():
return time.clock() * 1000.0
def doTime(start):
global min
global max
global avg
global sum
global count
diff = msec() - start
if diff < min: min = diff
if diff > max: max = diff
sum += diff
avg = sum/count
print "Curr {:.3f} | Min {:.3f} | Max {:.3f} | Max/Min {:.3f} | Avg {:.3f}".format(diff, min, max, max/min, avg)
h = 24
w = 24
while count < 1000:
start = msec()
#calculate the first 1000 numbers in the fibonacci sequence
x = 0
while x < 1000:
a = int(((((1 + math.sqrt(5)) / 2) ** x) - (((1 - math.sqrt(5)) / 2) ** (x))) / math.sqrt(5))
x+=1
count+=1
doTime(start)
Acontece que o Mac não está imune, mas é melhor em apenas 75% a mais para a execução mais lenta. Eu tentei rodar no Linux, mas não faria a resolução de temporização de microssegundos, parece que os números foram muito arredondados para o ms mais próximo.
Windows: Curr 2.658 | Min 2.535 | Max 9.524 | Max/Min 3.757 | Avg 3.156
Mac: Curr 1.590 | Min 1.470 | Max 2.577 | Max/Min 1.753 | Avg 1.554