00:00
好,接下来我们继续啊,那刚刚呢,我们是看了这个这个。Break continue啊这两个东西,那接下来呢,我们还是在说一个问题,在说什么呢?再回来说我们之前说过的一个质数练习啊,在这儿呢,我们来保存一下文件啊,我们来一个14。14我们这个文件呢,我们就是一个练习的一个优化。什么优化呢?我们先把质数练习啊,这个练习给它粘过来,CTRLCCTRLL粘过来,嗯,粘到这以后呢,这一段代码是我们刚才质数练习那个代码,我们这一保存一执行代码执行完了,功能上没有任何问题,对吧?但是这里边我们要说的就是以后我们到了工作当中,到了开发环境里,是不是说我们的一个项目,我们的一个程序把功能完成了,项目就完成了呢?哎,那注意当然不是了,那注意我们在开发的时候,我们完成功能,这个功能它属于业务逻辑,并不是说业务逻辑完成了就完成了,我们还要追求什么,我们还要追求一个程序的性能,也就是说我们在程序在运行的时候,我们是不是希望它的性能越快,我们就越越好啊,哎,越快我们就越高兴,那怎么就性能好,怎么就快了,那所谓的性能就是什么?我们这个程序从开始运行到运行结束,它。
01:31
我经历的时间越短,是不是就意味着我程序的性能越好啊,哎,同样一个功能,我执行了十分钟,你执行了一秒钟,那很明显一秒钟是不是性能更好啊,那同样我们是不是也希望我们这个程序,我的这个19行代码执行的速度越快越好啊,哎,或者这样我把代码呢,稍微的去清理一下啊,把我把我们把这些没用的先都给它去掉,哎,先去掉,那这个是我们整个代码一共11行,我们希望这个代码执行的速度是不是越快越好啊,诶越快越好,那这就涉及到我们的性能的一个优化,那问题来了,那我们怎么。
02:11
来优化,哎,那我们要想对这东西性能进行优化,我们得先明确一件事,我得知道它现在的性能到底是多少对吧?我得知道现在这个程序的执行到底花费了多长时间,对吧?那问题来了,我怎么知道啊?哎,怎么知道,那我是不是就需要测试一下这个程序运行所花费的时间呀?哎,那怎么测呀?哎,那我们是不是,诶我手里拿个秒表,我这边一边掐表,这边一边运行,结果一出来,我咔一掐停,我看时间呀,诶,当然不行了,我这是自己掐表,那玩意儿能掐的准吗?误差肯定特别严重,所以这个时候我们就希望需要用到我们Python的一个内部机制来计算我们程序的时间,的确是需要掐表,但是不是我们手动掐的,而是通过程序掐,在程序运行前,我们记录一个时间,在程序运行后,我们记录一个时间,然后把这两个时间一相减,是不是就求出这个?
03:12
去运行的时间了,哎,那问题来了,那我怎么计算呀?哎,我怎么计算呀,那注意这个是计算不了的,默认情况下我们是计算不了的,所以我们需要引入一个模块来对我们Python的功能进行扩展,注意这里边我们提到一个概念,我们叫做一个模块,诶通过模块我们可以对我们的这个Python进行什么呀?诶进行扩展,也就是说我们Python本身是一个语言,它本身具有一些功能,但是它并不会具有所有功能,因为如果具有所有功能会导致我们这个程序过大,所以在我们Python中,它只包含了一些必备的功能,而我们要增加功能,要扩展功能,我们就需要引入什么,引入模块啊,有模块,模块的具体东西我们后边讲完函数,我们会具体去说它,但是现在我们先知道你要用,你要扩展,就需要引入模块,先记住怎么用我们后边。
04:12
来解释怎么用啊,那现在我们可以什么呢?哎,我们可以引入一个time模块,哎,来统计我们程序执行的一个时间啊,Time模块那怎么引呀?哎,怎么引,我们用的是一个from,哎,From我们叫做一个time import一个这个星啊,Import一个星,哎,那这个就是一个time模块,那这是什么意思啊?哎叫从这个模块里边引入它的所有功能啊,引入它的所有功能,这样这个time模块就引进来了啊引进来以后注意了,在这里我们就可以调用一个time函数啊,我们就可以调一个time函数,这样我们先在我们的这个I豆里来演示一下。打开我们这个Python啊,打开它在这来演示一下,我们来一个哎,From一个这个time,我们来一个import一个星直接走引入完了,现在我们就可以调一个time函数,看到了吧,哎,我就可以调一个time函数,如果你没引入啊,没引入看着我重新打一个,重新打开一个,这个时候它是一个没引入的一个状态。
05:23
这时候你再调time,它是干嘛的,它是报错了,告诉你name容time is not DeFine,所以注意引入的作用就是引入这么一个time东西啊,这么一个time,好,那现在我们这是不是已经引入完了,哎,引入完了,哎引入完了以后我们来说一下这个作用,Time函数,哎,它可以用来获取我们这个当前的一个时间,那注意它返回的这个单位是什么呢?是我们的这个毫秒,哎,是秒啊,返回的单位是秒,所以注意当我们这儿来一个time,它就会干嘛呢?我们是不是这个time函数是不是在第五行执行的呀,它就会在第五行获取一个当前这个函数执行的一个时间,它会把时间所有的时间统一成什么呢?统一成秒啊,统一成秒,在这里就获取到这样一个时间,这是第五行代码执行的时间,好,那同理,我在这儿再执行。
06:23
一个在第19行,我再调一个time,那也就是说我在第19行这里是不是又获取了一个第19行代码执行的时间呀?哎,那现在我要求的是什么?我是不是要求我这个程序所执行的时间呀,那怎么办?我是不是把这两个时间一减就行了呀?哎,求一个时间差,就是我代码之间的时间,所以在这我来一个叫做一个begin be.begin开始的意思,在这儿我们来说一下,获取我们这个程序,诶开始的一个时间,然后在这儿呢,我们来再来获取一个我们程序,哎,结束的时间,结束的时间,然后在这我们来一个这个end啊,End,这都整完了,在这里我们来计算我们这个什么呀?哎,程序执行的一个时间怎么计算,我们直接来一个print,我们来一个N减去一个begin啊,N减begin是不是就这么时间呀?哎,注意它们的单位是一个。
07:24
秒啊秒,前面我也打印一个吧,打印一个我们这个程序执行,哎花费了冒号,诶来一个逗号诶那这样效果打印的时候,我们就会打印一个程序执行花费了多少多少时间,对吧?我们这一执行走一个呃,I me啊,这应该是一个看把T给删了是吧?哎,Time啊time这在执行一走是不是程序花费了000这么这么点时间是吧?这么点时间诶基本上可以忽略不计,基本上就是零秒对吧,零秒,那注意了,实际上我们这个程序直行的时间更短,为什么呢?因为我在这里是不是用了打印语句啊,而打印语句是比较耗费时间的,所以我们在测性能的时候一般不测打印语句,因为打印语句的时间是固定的呀。
08:11
所以在这里我们完全可以把打印语句给它注掉啊,给它注掉这时候我们再测,你会发现这个时间,诶这个注掉以后呢,带来问题了,住掉以后这if服是不是没内容了,哎,没内容了,我们写一个pass啊,这一执行是不是程序花了这么长时间,哎,那注意了,诶0.00几秒,还不到一秒呢是吧,可能三毫秒,诶三毫秒的时间,那这个时间是不是已经很快了呀?哎,注意这个时间的确是很快了,但是并不证明我们程序的性能好,为什么这么说,因为我们这个测试现在来说并没有意义,为什么没有意义呢?诶注意了,举个例子,哎,我们经炒看电视是吧,有这种田径比赛是吧,田径比赛跑的比较快的,什么这个博尔特是吧,外国的还有中国什么苏炳添是吧?诶那假如说,诶假如说你让这个博尔特苏炳添和我我们三个人来比赛赛跑。
09:10
比谁跑得快啊,比谁跑得快,那跑的距离是多少呢?跑的距离是半米或者是一厘米啊,我们赛跑一厘米跑,看谁跑得快,那注意这个能不能测出来,哎,不能测出来,因为这个距离太小了,对于我们来说可能都是迈一步,不是他跑的再快,他一厘米他得慢一步,对吧,我跑再慢,我因为我也是迈一步,所以如果我们比的是一厘米跑,这个比得出来,比不出来。比不出来,因为这个距离是不是太短了呀,哎,太短了,同理我们要测试一个程序直行的性能,现在我们这循环,这是不是才小于等于100啊,才从100个数里边获取所有的质数,这个数量级太小了,太小了就导致我们这个测试是没有意义的,所以注意在测试性能的时候,我们一定要把这个数给它弄大一点,我们现在是取100的,比如说我可以测一个什么呢?取1万的,哎,1万以内的所有的质数,对吧,这样这个数就大了,大了以后我们这个性能就体现出来了啊,这一保存,我们这一执行走一个你会发现我这个程序现在是不是卡在这里不动了,为什么不动了,现在我的程序就在运行,在从1万里边获取到所有的这个质数,现在就在做这个运算,你会发现这个速度是不是明显要慢很多呀,哎,你会发现花费多少,花费了12。
10:38
12.298秒对吧,诶12.298秒,我们先记录一下啊,在这里我们来记录一下,我在这儿记录吧,我们来说一下,这是我们这个优化前啊优化前。右画前我们先记录一下次数啊,我们这是1万啊,1万个数啊,1万个数是12.298秒,10.298秒,哎,这个其实已经很慢了啊,已经很慢了,我们再来看一个,我来一个10万个数,10万个数做好心理准备,可能他就执行不出来了啊,可能执行不出来了,我这一执行,哎,咱们先让他走着啊,现在走着他让他再在这儿去默默的执行,我们先不管它,他很有可能就执行不出来了,因为10万个数对于我们这个程序来说,现在执行起来会比较费劲啊,比较费劲,好,那现在我们现在的优化目标就有了,我们现在的优化目标是不是就是我让他1万个数比这个时间要要快呀,你比12秒要快,我们这是不是就等于有优化了,哎,那我们来看怎么进行优化,那怎么进行优化,现在我们先看一个位置,现在来看这,那这种优化在做的时候,我们看这儿啊,那现在咱们举个例子。
11:55
假如说现在我们这个数是100啊,我们就拿100举例子,100举例子,然后我们这个I是100,接等于二,接小于I是不是就皆小于100呀?哎,接小于100从二开始,那第一个数100摩以二,这时候是不是就等于零了?哎,100除以二,100已经能被二整除了,是不是就证明二一百已经不是质数了?哎,已经不是质数了,那我问你,当100能被二整除的时候,说明100已经不是质数了,那既然100已经不是质数了,我还有没有必要再去看100能不能被34567891直到99这些数整除了,没有必要了吧,因为他已经能被二整除了,三到99能被能不能整除,它这个时候已经没有任何的意义了啊,已经没有任何的意义了。所以这个时候,如果。
12:55
你还在去往下检查的话,是不是就在浪费啊,哎,就在浪费,那同理呢,问你了,这我们有没有继续检查。
13:03
你们想想,当我100能被二整除的时候,我在这有没有继续检查,哎,肯定有,因为我这个循环是不是一直没有退出啊,没有退出它就会一直接甲等于加仪,会一直去检查3456,而然而这些检查还有没有意义了,哎,没有任何意义,所以这时候注意我们来说一下,旦进入判断,则证明我们这个I啊,一定不是质数啊,一定不是质数,此时我们的内层循环没有继续执行的必要了,如果内层循环再执行,它是不是就是浪费性能,你没必要做无用功,那就是对性能的一个浪费,所以这个时候我们要想提升性能,是不是一旦进入判断,则证明它不是质数,不是数,此时我是不是可以退出内层循环呀,怎么退出?哎,就是我们的瑞。
14:03
哎,Break,哎,来退出我们的内层循环,这直接写一个break,注意写哪写的是if里边,为什么?因为只有进入判断才证明它不是质数吧,只有进入判断我们才有必要退出,如果你写外边,那完了这功能就错了,所以注意一定要写到if的里边啊,写到if里边这样一保存,那我们来看看性能有没有提升啊,性能有没有提升,来我们来看看它吧。这个玩意儿是不是还没有执行出来呢,没有执行出来我们就关了啊,不管它了,这里边儿我们来看看需不需要给他停一下。嗯,我们的进程啊,应该他自己已经停了,那就不管它了,我们在这现在这个是不是我优化以后的还是1万个数啊,1万个数我这一保存,我们来执行一下走一个。诶,多少了1.577秒啊,1.577秒,我们来记录一下啊,这是我们的第一次优化。
15:03
第一次优化啊,我们还是。2341万个数啊,1万个数,我们是1.577秒,那这样我们会发现我们加了这么一个break,是不是就优化了十多十倍左右吧,诶将近十倍不到十倍啊,不到十倍也也差不多了,诶八九倍的样子啊,八九的样子,那这个就是我们的一个优化,所以注意break什么时候用,我们可以用break来结束那些没有必要去执行的循环,那这时候我们来看一下,那同学说老师你这是优化完了,那结果对不对啊,哎,结果对不对,那我这样我还是改成100,我来验证结果,因为我1万的话,验证结果我也看不出来,我还改成100,我来验证结果看对不对,跟我们之前的结果一不一样,我们来看一下,二三五七十一十三十七十九,23,二九三十一是不是一模一样啊,诶一模一下,所以这个时候结果也是对的,那他就没有没有问题了啊没有问题了,好,那接下来再看,那你这是1万个,我们来一个10万呢,刚才我们这个优化前,我们1234。
16:07
一千一万十万十万个数的时候,我们这里边是不是没有没有结果呀,哎,没有结果或者说很慢了啊,很慢了没有执行出来,而现在我们这优化以后,我们来看一千一万十万,哎10万个数,那这个时候我们来看看它是什么结果啊,它是什么结果来在这儿我们来一直行啊,一直行再来看,但是这个速度肯定还会有一点点的慢,但是它你要稍微等一下,肯定是能出结果,那我们稍微等一下。呃,看来这个速度也不是很乐观,我们来看一下现在CPU是不是已经占满了,哎,占满了在计算着呢啊,让他先计算,当然这个东西根据你计算机的性能,可能你性能好的话,这个计算机快一点,那性能差的话,计算机稍微的慢一点啊,根据不同的计算机性能也不一样,好这个东西我们还是先给它放在让它自己计算,能不能算出来,待会儿我们再说,那接下来我们再开,这是我们的第一次优化,那是不是第一次优化就完了呢?那你很明显1万个数才行了,但是10万个数这个速度是不是还是难以接受啊。
17:16
也是,他是不是也有可能执行不出来呀,所以这个时候我们还要想,我们的这个东西,我能不能再做进一步的优化。能不能再做进一步优化?哎,那这里边我们来看一下啊,我们来看一下,或者这样,接下来呢,我们这先停一下啊,停一下你们自己来尝试着,第一个事先来测试一下你这个代码的执行时间啊执行时间,第二个事尝试通过break来对这个代码进行优化啊,通过break来对代码进行优化。第三件事再思考一下能不能有优化的空间了,提示一下哪个位置内层循环,这个位置可以去修改,这个地方改了以后我们的性能会有大幅度的提升啊,大幅度提升你会发现我这代码还没提升出来呢,好,我们先不等他了,接下来剩下的时间交给你们自己来写一下啊,我们来评。
我来说两句