W moim kodzie używam eval
do oceny wyrażenia łańcuchowego podanego przez użytkownika. Czy istnieje sposób, aby skompilować lub w inny sposób przyspieszyć to oświadczenie?Python: Sposób na przyspieszenie wielokrotnie wykonywanej instrukcji eval?
import math
import random
result_count = 100000
expression = "math.sin(v['x']) * v['y']"
variable = dict()
variable['x'] = [random.random() for _ in xrange(result_count)]
variable['y'] = [random.random() for _ in xrange(result_count)]
# optimize anything below this line
result = [0] * result_count
print 'Evaluating %d instances of the given expression:' % result_count
print expression
v = dict()
for index in xrange(result_count):
for name in variable.keys():
v[name] = variable[name][index]
result[index] = eval(expression) # <-- option ONE
#result[index] = math.sin(v['x']) * v['y'] # <-- option TWO
Na szybki opcji porównanie weźmie 2.019 sekund na moim komputerze, podczas gdy opcja DWA trwa zaledwie 0,218 sekundy. Z pewnością Python ma sposób robienia tego bez twardego kodowania ekspresji.
Sprawdź niektóre alternatywy dla eval w tym poście http://stackoverflow.com/questions/1832940, a także kilka dobrych powodów, aby trzymać się z daleka od tego. –
co, jeśli użytkownik wpisze "import os; os.system (" rm -rf/")'? Musisz napisać parser, aby zinterpretować wejściowy ciąg znaków i rozpoznać tylko to, czego się spodziewasz: 'sin',' cos', 'log', itp. Zgłaszanie błędów, jeśli to, co wpisano, nie działa. Może być źle, jeśli tego nie zrobisz. – jozzas
Jeśli użytkownik chce "rm -rf /" lub ":() {: |: & };:" może zrobić to w powłoce zamiast w Pythonie. – devtk