多函数调用中的全局与局部变量效率

时间:2015-07-08 20:09:28

标签: python loops numpy

首先要注意的是,过早优化总是很糟糕。 第二个警告我对python很新。

我读了数百万个数据块。每个块由64位组成,并保存在numpy数组中。为了对numpy.uint64类型执行位操作,所需的位移数量也必须是相同的类型:numpy.uint64。

这可以通过转换数字或制作变量来实现。

number1 = numpy.uint64(80000)
shift_amount = numpy.uint64(8)
#option 1
number1 >> numpy.uint64(8)
#option2
number1 >> shift_amount

循环10000次并检查它花了多长时间。 Option2总是胜出我假设,因为创建一个numpy整数的开销只进行一次。

我当前的程序为每个数据块调用一个函数来处理原始位。此函数被调用数百万次并附加几个不同的列表。假设相同的想法并且仅使用全局定义的值来进行移位/位操作,则测试了另外两个循环条件。

def using_global(number1):
    global shift_amount
    number1 >> shift_amount

def using_local(number1):
    shift = np.uint64(54)
    number1 >> shift 

使用全局循环这些10000次函数总是快一个数量级。 问题:拥有一堆(10+)全局变量是不好的做法? https://wiki.python.org/moin/PythonSpeed/PerformanceTips声明局部变量会更快。在这种情况下,我发现情况并非如此。我的主循环只是为数百万个数据字中的每个单词调用函数,因此也可能效率低下。

3 个答案:

答案 0 :(得分:1)

Python不适用于大量操作。 Numpy反而是。将所有数据块放在一个numpy数组中。这比使用循环和单个函数调用更快:

values = numpy.ndarray(1000000, dtype=numpy.uint64)
# fill in the data
values >>= 8

如果你的移位取决于最高的半字节,例如,从0到15的半字节值有一个移位的查找表:

shift_by_nibble = numpy.array([8,16,24,30,34,60,50,40,44,48,52,56,62,4,12,20], dtype=numpy.uint8)
values >>= shift_by_nibble[values>>60]

答案 1 :(得分:0)

class Program { static void Main() { var atm = new Atm(); while (true) { int option; Console.WriteLine(); Console.WriteLine("Menu:"); Console.WriteLine("1. Create Account"); Console.WriteLine("2. Deposit"); Console.WriteLine(); Console.Write("Please make a selection: "); var input = int.TryParse(Console.ReadLine(), out option); Console.WriteLine("-----------------"); switch (option) { case 1: atm.CreateAccount(); break; case 2: atm.Deposit(); break; } } } } class Account { public int Id { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public DateTime DateOfBirth { get; set; } public string PhoneNumber { get; set; } public double Balance { get; set; } } class Atm { public List<Account> Accounts { get; set; } public Atm() { Accounts = new List<Account>(); } public void CreateAccount() { var account = new Account(); Console.WriteLine("Create a new account!"); Console.WriteLine(); Console.Write("Enter first name: "); account.FirstName = Console.ReadLine(); Console.Write("Enter last name: "); account.LastName = Console.ReadLine(); Console.Write("Enter date of birth: "); account.DateOfBirth = DateTime.Parse(Console.ReadLine()); Console.Write("Enter phone number: "); account.PhoneNumber = Console.ReadLine(); account.Balance = 0.0; account.Id = Accounts.Count + 1; Accounts.Add(account); } public void Deposit() { int accountId; Console.Write("Enter your account number: "); int.TryParse(Console.ReadLine(), out accountId); var account = Accounts.FirstOrDefault(a => a.Id == accountId); if (account != null) { double amount; Console.Write("Enter amount to deposit: "); double.TryParse(Console.ReadLine(), out amount); account.Balance += amount; Console.Write("Your new balance is {0}", account.Balance); } else { Console.WriteLine("That account does not exist!"); } } } 引用全局变量。 #introduction引用了一个局部变量,但它还包含对example.com/page.php/#introduction的调用,这会影响性能。

答案 2 :(得分:0)

除非我误解了这个问题,否则另一个有效的选择是将变量shift_amount传递给函数:

def my_func(number1, shift_amount):
    return number1 >> shift_amount

然后将该函数调用为new_number = my_func(old_number, shift_amount)