python for循环计算速度很慢

从一个比较大的数据文件中读取数据,是一个80k乘10k的矩阵,保存在pickle文件中,循环读取然后做一些计算处理,最后记录并保存为同样矩阵大小的文档,代码写好之后,开始测试,跑一个循环就要6s左右,一共80k个循环,就是133.3333334小时,要命,耗不起。
先上代码,再细究这个问题还有解决办法:

	...
	with open(save_path, 'rb') as fi1:
	    result = pickle.load(fi1, encoding='iso-8859-1')
	n, fx = zip(*result)

	merge_result=[]
    #starttime = datetime.now()
    for i in range(0, len(result)):
        #starttime = datetime.now()
        f_x = np.array(fx)[i]  #problem is here
        name = result[i][0]
        full_result= merge_result(f_x)
        merge_result.append((name, full_result))
        if i % 1000 == 0:
            print('processing result:{}/80000\r'.format(i))
        #endtime = datetime.now()
        #print('consuming time:', (endtime - starttime))
        #starttime = datetime.now()
        
	...

按照上面这段代码,跑一个循环耗时是5.92s左右,用的显卡是Titan xp,太费时间了,速度这么慢,非常不合理,对各个部分的耗时都做了计算,最后发现问题出在f_x = np.array(fx)[i]这里,因为fx是一个元组,当时的理解是需要转换成array数组的形式进行计算,后来了解了一下,在Python中其实是没有数组这个概念的,只有列表(list)和元组(tuple),还是基础的问题,对python理解不够。
问题找到了,解决起来也有方向了,后来发现其实根本不需要转化成numpy的数组形式进行计算,因为通过序号检索得到的结果就是数组的形式,不需要再对整个矩阵进行转化成array操作。
代码修改后如下:

	...
	with open(save_path, 'rb') as fi1:
	    result = pickle.load(fi1, encoding='iso-8859-1')
	n, fx = zip(*result)

	merge_result=[]
    #starttime = datetime.now()
    for i in range(0, len(result)):
        #starttime = datetime.now()
        f_x = fx[i]  #problem is here
        name = result[i][0]
        full_result= merge_result(f_x)
        merge_result.append((name, full_result))
        if i % 1000 == 0:
            print('processing result:{}/80000\r'.format(i))
        #endtime = datetime.now()
        #print('consuming time:', (endtime - starttime))
        #starttime = datetime.now()
        
	...

修改完之后,再测试速度,跑一个循环只需要0.127s左右,这就舒服多了,效率也高了很多。
速度大幅提升啊!

关键还是对基础的知识了解得不够,多学习多积累,共勉。

Python 中,使用一些优化技巧可以提高 for 循环的性能。以下是一些常用的方法: 1. 使用列表解析(List Comprehension)或生成器表达式(Generator Expression):列表解析和生成器表达式可以在循环迭代的同时创建新的列表或生成器对象,比传统的 for 循环更高效。它们利用了 Python 的内建优化机制,可以减少循环次数和内存占用。例如: ```python # 使用列表解析 new_list = [x * 2 for x in old_list] # 使用生成器表达式 new_generator = (x * 2 for x in old_list) ``` 2. 使用内置函数:Python 提供了许多内置函数,可以在循环中使用,以提高性能。例如,`map()` 函数可以将一个函数应用到迭代对象的每个元素上,`filter()` 函数可以根据条件过滤元素,`reduce()` 函数可以对序列进行累积计算。这些函数能够以更高效的方式处理循环操作。 3. 使用迭代器(Iterator)和生成器(Generator):迭代器和生成器是 Python 中用于惰性计算的机制。它们允许逐个产生元素,而不是一次性生成整个序列。通过使用迭代器和生成器,可以节省内存和计算资源,并提高循环的效率。 4. 使用并行处理:对于一些可以并行处理的任务,可以使用并行计算库(如 `multiprocessing` 或 `concurrent.futures`)来并行执行循环,从而提高整体性能。 5. 优化循环体内的操作:在循环内部,尽量避免执行耗时的操作或重复计算。例如,将重复计算的结果缓存起来,避免重复访问文件或数据库等。 6. 使用 Cython 或 Numba 进行编译优化:可以使用 Cython 或 Numba 这样的工具,将 Python 代码编译成 C 语言或机器码,以获得更高的执行速度。这些工具可以将循环中的代码进行优化,并提供更高效的执行性能。 请注意,优化 for 循环的效果取决于具体的代码和应用场景。在某些情况下,重构算法或使用其他数据结构可能会更有效。因此,建议根据实际情况选择合适的优化方法。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值