程序的运行时间以及数据处理过程中的一些性能优化

本文探讨如何测定程序运行时间复杂度,并介绍了time、timeit、profile等模块的使用。此外,文章还分享了在数据处理中的一些性能优化技巧,如避免过多列、优化条件取法以及利用map()函数实现并行化处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

怎么测定程序运行的时间复杂度

性能的优化一般从两方面来考虑,时间复杂度和空间复杂度,在如今硬件那么发达的情况下,时间复杂度的优化就显得更为重要了,有时候甚至要以空间换时间,所以这里结合自身项目的实践,就简单说一下程序运行时间上的优化。

测定程序的运行时间

要想优化程序,得先知道哪部分程序需要优化,下面是几种常用的检测程序运行时间的方法:

  1. time模块
    time模块用法很简单,就是在程序运行的开头和结尾分别检测一个时间,然后 (结束的时间 - 开始的时间) 就是程序运行的时间。常用的有time()和clock(),两者的区别参见:https://blog.youkuaiyun.com/wonengguwozai/article/details/80680699

    # 以clock()为例,两者用法完全一样
    import time
    t_start = time.clock()
    # 要检测的代码块(函数等)
    fun()
    t_end = time.clock()
    exec_time = t_end - t_start
    print(exec_time)
    
  2. timeit模块
    timeit模块的用法比较灵活,有多种用法,像timeit.default_timer()与上述用法一样,这里不重复了,简单说说常见的几种用法,详细的可以看看timeit的documentation。

    代码行界面可以用如下命令(不包含尖括号):
    python -m timeit <要执行的命令>

    python 界面可以如下:

    import timeit
    def fun():
    	pass
    timeit.timeit(stmt = fun, number = 1000)
    

    如果是在jupyter notebook中,可以直接调用%timeit:
    这种操作是把代码循环跑几遍取平均值,如果代码运行时间较长,不建议采用这种方法。

       #要执行的代码块注意不包含两端的尖括号
       %timeit <要执行的代码块>
    
  3. profile模块
    正如名字所指的这样,profile模块可以剖析你所要执行的代码块,找出每一部分所耗费的时间占比,当你不知道程序中哪一块需要优化时,用此方法先找到需要优化的部分,有目标才更有针对性。
    这一部分可以用cProfile, line_profiler等,这里只简要介绍一下个人比较喜欢的line_profiler,它对程序的每一行进行分析,找出其运行时间的占比。

    #需要安装line_profiler
    from line_profiler import LineProfiler
    # 仅列举一个简单的例子
    def fun(a,b):
    	a * b
    	a ** b
    	b ** a
    	return a + b
    lp = LineProfiler()
    lp_wrapper = lp(fun)
    lp_wrapper(3,5)
    lp.print_stats()
    

    如果是在jupyter notebook中,可以用line_profiler 扩展

    #load line_profiler扩展
    %load_ext line_profiler
    def fun(a,b):
    	a * b
    	a ** b
    	b ** a
    %lprun -f fun fun(3,5)
    

除此之外,还有其他好多方法来检测程序的运行时间,stackoverflow上面有一个问题几乎包括了所有方法,感兴趣的可以参考:
https://stackoverflow.com/questions/1557571/how-do-i-get-time-of-a-python-programs-execution

数据处理上的一些优化

前面讲了一大堆怎么测程序的运行时间,以及怎么找需要优化的地方,现在终于到正题了,这一部分只介绍我最近用到的几个方法,以后还会继续更新,仅供参考。

data analysis避不开pandas 和 numpy, 接下来就分享一下我在工作中遇到的几个方法,小白刚刚入行,与大家相互学习

首先是pandas:,numpy后续更新

1.column数量
pandas本身已经进行过优化,但是在做大数据处理的时候,column过多会影响程序的运行速度,所以能不增加column可以不增加,只对某些column做处理的话可以单独取出来处理,然后再放回去.

2.切片的取法
假设:df.columns = [‘a’,‘b’,‘c’,‘d’]
取法1:df[df.a == 1][df.b == ‘new’][df.c == False]
取法2:df[(df.a == 1)&(df.b == ‘new’)&(df.c == False)]
取法1不仅会报警告,而且速度会很慢,官方文档中也有说明,因为每一次取的条件都会生成一个新的dataframe,很浪费时间
而取法2 则是先把各种条件取交集,然后再一次取出,速度有可能是取法1的4-5倍
3. 使用map()
使用pandas的好处就是可以把大量的数据做并行处理,如果会里面的每个数据或每列数据单独操作的话会非常费时间,这个时候就要想办法能不能使用pandas里面的map()函数,或apply()进行并行化操作,速度提升到你想不到,40-50倍,甚至上百倍都有可能。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值