为什么在Python中将函数分配为变量更快

时间:2018-09-06 13:45:56

标签: python-3.x function variables

今天我观察到了使用Python的有趣行为。

def f():
    ls1 = []
    for x in range(1000000):
        ls1.append(x)
%timeit f()
77.2 ms ± 1.83 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

并测试了第二个功能。

def f2():
    ls1 = []
    lsa = ls1.append
    for x in range(1000000):
        lsa(x)        
%timeit f2()
56 ms ± 566 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

将附加值分配给变量比在循环内部使用附加符要快。

为什么第二个功能更快?

2 个答案:

答案 0 :(得分:2)

因为在第二个函数中,您已经具有对该方法的引用,并且可以在每次迭代中直接调用该方法,而在第一个函数中,它必须首先找到{{1}的append方法}在每次调用之前都首先迭代。

答案 1 :(得分:2)

Python是一种动态语言。属性查找与字典查找类似,因此在第一种情况下,您首先在本地范围内查找#include <stdio.h> #include <stdlib.h> //PROTOTYPE int operationSwitch(); //Function to calculate total of operand1 and operand2. int menu(); //Function for main menu. int iResume(); //Function to continue the program or not. char iOperation = '\0'; //choices (1-7) float operand1 = 0; //number 1 float operand2 = 0; //number 2 float operandTotal = 0; //total int testPrime, counter, prime = 0; char cContinue = '\0'; char symbol = '\0'; int main(){ menu(); return 0; } int menu (){ do { printf("\nPlease choose an operation: "); printf("\n(1) Addition\n "); printf("\n(2) Subtraction\n "); printf("\n(3) Multiplication\n "); printf("\n(4) Division\n "); printf("\n(5) Modulus (integers only)\n "); printf("\n(6) Test if Prime (integers only)\n "); printf("\n(7) Exit\n "); printf("\nChoose (1-7):\t"); fflush(stdin); scanf(" %c", &iOperation); } while (iOperation < 49 || iOperation > 55 ); if (iOperation != 54 && iOperation != 55){ //ASCII 55 == 7) printf("\nEnter number 1:\t"); fflush(stdin); scanf(" %f", &operand1); printf("\nEnter number 2:\t"); fflush(stdin); scanf(" %f", &operand2); } operationSwitch(); /*** RESULTS ***/ if ( symbol == '/' && operand2 == 0) { printf("\n\t-----| Answer: %.2f / %.2f = Undefined |-----\n", operand1,operand2); } else if (iOperation != 54) { printf("\n\t-----| Answer: %.2f %c %.2f = %.2f |-----\n", operand1, symbol, operand2, operandTotal); } iResume(); return 0; } //End Menu /********************************* SWITCH FUNCTION *********************************/ int operationSwitch() { switch (iOperation) { case 49://1 Addition Ascii 49 == 1 43 == + operandTotal = operand1 + operand2; symbol = '+'; break; case 50: //2 Substraction operandTotal = operand1 - operand2; symbol = '-'; break; case 51: //3 Multiplication operandTotal = operand1 * operand2; symbol = '*'; break; case 52: //4 Division operandTotal = operand1 / operand2; symbol = '/'; break; case 53: //5 Modulus operandTotal = (int)operand1 % (int)operand2; symbol = '%'; break; case 54: //6 prime = 1; printf("\nEnter number to be tested for prime: "); fflush(stdin); scanf(" %d", &testPrime); for(counter = 2; counter <= (testPrime/2); counter++ ) { if(testPrime % counter == 0) { prime = 0; break; } } if (prime == 1) { printf("\n\t| %d is a prime number. |\n", testPrime); } else { printf("\n\t| %d is not a prime number. |\n", testPrime); printf("\n\t| %d * %d = %d \n", testPrime/counter, counter , testPrime); } break; case 55: printf("\nGood Bye\n"); exit(0); break; default: printf("\nYou entered: %c - Please try again ", iOperation ); break; } //End Switch iOperation return 0; } //End Switch Function /********************************* RESUME FUNCTION *********************************/ int iResume() { printf("\nWould you like to try again?\nPress \'Y\' to go to menu,\nor any key to quit?\t"); fflush(stdin); scanf(" %c", &cContinue); if (cContinue == 'y' || cContinue == 'Y'){ menu(); } else { printf("Good Bye!\n" ); } return 0; } ,然后在ls1对象上查找append,每次迭代1000000次。在第二种情况下,您仅在ls1上查找append,然后在本地范围内查找ls1的一百万次迭代