00:00
那这个功能我们是做完了,基本功能能实现了,但是这个代码,这个代码还有一些优化的一些空间。对,你要是在公司里边写这个代码,虽然功能能实现,但一般来讲你写的这个代码就质量不太高,就将来的真正让用户用的时候,特别高并发访问情况下,那我们要这个这个代码应该运行的比较慢。效率比较低,知道吧,当然功能是做好知道吧,哪个地方效率比较高,比较低,我们这个给大家分析一下,然后我们改造一下,哪地方是这个地方,我说这一行代码效率是非常低的,就哪一个代码呢这个。就这一个代码,这个这一行代码效率是非常低的。诶,你说老师,诶这张代码很简单,效率怎么能低了,你写的时候简单,但是它底层实现的时候特别复杂,就这个right这个方法。谁实现了阿帕奇POI这个插件实现了,大家可以,他这些都是开源的,它有源代码。
01:05
你可以看看他源代码,这个方法里边非常复杂。做了大量的工作,而且对,而且他这个什么,而且他这个方法运行的效率特别低,不但里边代码多,而且它运行效率非常低,他怎么低了拉是这我说他访问磁盘了,访问磁盘了,这个代码访问磁盘了,怎么访问磁盘了,但你想一想啊,这个代码执行之前,Excel文件那些数据都在哪存着呢。对,那些市场活动数据都从哪都在哪存着呢?在数据库,数据库我们已经查出来了。查出来放哪了?对,放内存,为什么放内存里边呢?因为都放到这个什么,都放到这个work有它生成的这些对象里边了,是不是这样的,都放到什么,Shift对象,Road对象,S对象,把市场工动那些数据全放到什么,其实全放到这个对象里边,这些对象都是由它延伸出来的,有他创建的,它都保存了这些对象的引用。
02:10
所以在这个什么,在这一行代码执行之前,我们那些市场活动信息全在这个对象里边了。对象大家都知道在内存里边,所以在这个代码执行之前,这些数据都在内存里边。都在内存里边,在内存里边,但这行代码执行完之后呢,这些数据跑到哪去了?对,跑到这个文件里边。知道吧,为什么?你看这个方法不就是把work book里边这些数据写到文件里边吗?就写到文件里边了,写到Excel文件在哪存着呢?对,在硬盘或者叫磁盘里边存储的,所以这个代码虽然我们没看到他代码怎么实现的,我们一定能猜出来这个代码一定是什么做了,把内存里边数据写到磁盘里边,他一定做到这个事儿了,要不然的话,不可能说内存里边数据存的好好的,然后执行完它之后跑到磁盘里边了,不可能是这样的,知道吧,所以他在他一定访问到磁盘了,你们老是访问磁盘,怎么访问磁盘效率是最低的,对,只要访问磁盘。
03:20
我们的程序不管什么时候,只要一旦访问磁盘,以任何形式访问磁盘,不管是写数据还是查数据,效率都是最低的,这为什么低?但你想你的程序是运行的内存里边的,你要是什么,不管查还是写出去,你要访问磁盘,你得建立从内存到磁盘的一个连接。建立连接本来就很耗时间,怎么建立的你也别管,这都计算机的原理了,反正是从内存访问磁盘效率是非常低的,它得建立到磁盘的连接,而且不但建立连接很消耗效率,网络上面不管查数据还是取数据,从磁盘上他都得去到磁盘上去找那些数据所存储的磁道是吗?但我们以前学这种计算机原理的时候,大家都知道这些磁盘都有磁道,是一个一个磁道,磁道什么磁道就跟他跑道一样是吧,就给那家跑道一样,一个一一圈一圈的,然后这这这磁道怎么了?磁道上面可以刻录这些什么电,电信号,可以刻录电信号,什么电信号,就电流的高低,高低在我们来看来就是什么010101是么,全什么全刻到这些词道上,那你不管写出去还是还是读出去,都得找磁道,写出去,你要找写到哪个磁道上面,然后读出去,你要是找从哪个。
04:41
迟到读知道吧,所以这个效率是非常低的,应该说。只要一旦访问磁盘,效率就非常低了。啊,所所以大家我们以前老师给大家前面阶段给大家老师讲数据库的时候,老师给老师应该给大家提过是吧,我们Java程序访问数据库是不是效率非常低啊,效率非常低,老师跟大家说尽量少访问数据库,是不是这个意思?
05:04
为什么尽量少访问数据库?因为数据库里边数据存到哪了?数据库里边数据存到内存里边还是存到存到磁盘上面了,磁盘对磁盘,就为什么磁盘上面,因为因为你写到数据库里边,数据电脑关了是不是还有啊,下次开机是不是还有啊,说明他写到磁盘上面了,那你的程序运行的内存里边你什么,你要访问数据库的话,你就访问磁盘了,不管写数据还是读数据效率都非常低,所以以前老师给大家讲什么,我们以后写程序尽量少访问数据库,能不访问就不访问,能少访问就少,就是因为它访问磁盘了,知道吧,那么我们说访问数据库效率低,因为访问磁盘了,我们现在访问文件。也是访问磁盘这个效率也低,只要访问磁盘,不管以什么形式访问磁盘效率都低,甚至我们直接写磁盘访问数据库效率还低呢,为什么?因为数据库是一种软件,大家都知道,因为数据库存数据的时候,往磁盘上存数据的时候呢,他把磁盘划分了几个区域,他做优化了,所以你访问数据库效率还稍微那么高那么一点点呢。
06:14
但是你要直接访问磁盘,你的效率还不如访问数据库,所以我说这个代码往磁盘上写数据的时候,效率非常低,它不次于你访问一次数据库,这个这个效率的损失。它占内存占CPU知道吗?所以这个代码是非常低的,那么第一怎么了?用户你导出市场活动执行一遍这个代码,他导出市场活也执行一遍这个代码,如果大家都导出这个代码会频繁的执行,那你损失一点效率,他损失点效率,那整个服务器就忙不过来了,服务器的压力就非常大了。所以我们说这个代码就这一行代码效率非常低,就是因为他把内存里边数据写到磁盘上面了。访问磁盘了,这个代码效率非常低,好,这是一个下边还有一个代码效率非常低,哪一个呢?这个地方我说这个循环成了。
07:10
这个循环,这个效率也是非常低的。这这个循环这个灯效率非常低,这个为什么低。那你看一看啊,这个代码他告我说他是干什么的,对八八什么这个文件里边的数据是吗?读到内存里边是不是输出到浏览器的,输入浏览器的,那你想一想啊,是输入浏览,其实就输出到这个输出流里边了,知道吧,这个代码执行之前,市场活动这些数据在哪存着呢。对,是不是在这文件里边存着的文件,是不是在磁盘里边存着的,对,在磁盘执行之前,在磁盘里边的这个这个循环执行完之后呢。这些数据都跑到哪了?跑到这个auto put流,跑到这个输出流,输出流在哪呢?对内存这边了,所以这个代码正好是吗?以前执行之前数据在磁盘上了,执行完之后呢,数据跑到内存里边了,知道吧,它也是什么读磁盘了,刚才是往磁盘上写,就把内存里边数据写到磁盘上边,现在它是从磁盘上的去读。
08:22
把数据读到内存里边。知道吗?读也得找渠道,也得建立跟硬盘的连接,所以它的效率也不次于你访问一次数据库,知道吧,所以它有这两个代码,你知道吧,这两个代码相当于我们每次导出设库数据库,就像不次于你访问两次数据库,就每次导出一个市场活动,不次于你是么?不次于你这个访问两次数据库,所以在高并发访问的时候,大家都导出的时候,你这个对服务器的压力是非常大的。所以下边我们就考虑如果如何解决一下,那怎么解决一下它,我们可以分析一下是吧,刚才上一个过程write的时候,它什么是把内存里边数据,然后呢,访问磁盘写到磁盘上,它呢。
09:13
是把磁盘上的数据呢。把磁盘上的数据,然后呢,读到内存里边,是不是这样的,读到内存里边。知道吗?他俩操作的数据是同样的,同样的数据吗?对,都是市场活动期,都是市场活动的那些数据,所以大概那这个时候你就发现了吧,这两个过程是完全是个逆过程,知道吧,一开始市场活动的信息在内存里边,我非要写到磁盘上边,然后再从磁盘上再读到内存里边,你这不是没事找事吗?同样的数据先写到磁盘上,再从磁盘上读到内存里边。那我们能不能这样,你别往磁盘上写了,你也别从磁盘上读了,干什么?同样的数据本来在内存,就从这个内存到这个内存不就行了吗?
10:04
这样不就可以了吗?那这个内存上这个内存是沃不可,这个内存叫out STEM。那从这一块内存到这一块内存不就行了吗?那这样的话就不用防护磁盘了,那你说从内存到从内存到内存效率很高啊,为什么不用建立到磁盘的连接,不用找硬盘的磁道了。所以这个效率就非常高了,那关键是现在问题是我们这个过程分析了,能不能从这个内存work book这个内存到直接到这个内存呢。能不能直接过去呢?那你就看Java题内提供这种语法。正好巧了是吗?正好这一个类里边有这个work book这个对象里边有个方法他干什么,他能够把它里边数据不用写到磁盘上了,能够直接输出到一个输出流里边。哪一个输出流,我这个地方正好有个输出流,这个输出流去连着浏览器,直接让他输出到这个输出流里边,这个输出流由连着浏览器往这里边灌数据,直接从浏览器出来了。
11:10
知道吧,所以呢,我们就准备这样了,这个地方我们就改造一下,怎么改造,说这个地方你就别往磁盘上写了,这个东别往磁盘上写了,那四个数据现在都在work book里边是吧,你就直接在直接什么在work book里边就行了,别往磁盘上写了,那这个地方呢,你也别从磁盘上读了。你也别从磁盘上读了,知道吗?那干什么,直接从这个work,不直接写到这个输出流里边,那怎么写,正好这里有个方法。Work里边有个方法叫right,哪一个大家看要这个输出流,看到吗?这个输出流。然后这个数,它这个数轴是个。我们这个地方正好一个auto得到了,然后呢,你把这个auto stream传给他,他就会把把它内存里边数据直接写到这个输出流,如果那正好这个输出流正好是连着浏览器,那往这个浏览器好像一个管道一样,你往这个管道里边灌数据,浏览器就能拿到。
12:17
知道吗?所以正好是这。所以就不用往磁盘上写,也不用从磁盘上读了,直接这么写就行,写完之后再看我们说那这个地方把沃可不可关了就行,那这个地方这个地方也给他。这个那这些给它注释掉,然后呢,你因为你不不往磁盘上写了这个这个也不用管它了,然后呢,写完之后把work book关一下就行。Close就行,知道吧,这样的话那我们就可以了,直接从内存到内存。就是我们还说到这样。
13:01
对,就这。对,直接写到浏览器上面知道吧,怎么写到,就因为这个我们从程序里边通过out,从浏览器建立一个管道啊,你通过这个什么,往这个管道里边灌出去,这不就能拿到啊,我们说流不相就相当于管到吗?往管道里边灌出去能拿到。其实给你这个道理一样,给你这个道理一样,你这个大家看这个输出流不就是什么连着管道吗?你从这里边以前是读一个buff,往这个管道里边灌一个八分,我这个直接往里边灌一个什么,也是灌这个流,他也直么从那边就出去了,知道吧。所以这是我们说的这个过程。所以这样的话,我们这个效率就高了,功能肯定完全一样了,而且更重要的一个地方呢,不用临时生成一个文件了,你要如果临时生成文件好了,大家都什么都导出的时候,每一个人生成一个文件,每一个生成文件,你这个服务器磁盘文件也太多了啊。
14:05
所以这个地方压根就不用生成文件。好,这样的话,大家我这个代码就改造好了,改造好之后下边我直接启动服务,大家你看再运行一下,这个效果跟刚才那个效果完全一样,只不过他这种效率就提高了,知道吗。所以大我们说我们写代码不但功能能实现,还要能够让运行效率也要提高,这样才是高质量的代码,知道吧。啊,当然虽然功能的实际验,如果是运营效率太低的话,特别是互联网项目的话,对你做的时候应该说测试部分人一下子能测出来,就他有一些这种测试工具是测试工具,就是人家写这个程序,同样的这一个业务,人家执行那种半秒就执行出来了,那你执行得执行好几秒,特别高并发访问的时候,那你更慢,所以这个时候你有可能给你提示bug了,知道吧。好,然后呢,这个地方继续玩,然后呢来登录再来测一测,然后呢,市场活动,我们现在再来导出来的看再来导出一样的道理,一样的也能输出看到吗。
15:12
No。嗯。啊,当然你说这个好像还还没有那么快是吗?啊,因为这个这个是我这不是我们程序的原因,这是从浏览器到服务器建立这个连接,本来就需要时间知道啊,当然我们现在这么不是高并发的情况下,这个效率提提升的不明显,知道吧,这是我们知道,但你打开这个文件你知道。跟我们刚才那个完全一样啊,这是我们说的这个关于抖出市场活动呢,我们就给大家说到这了,导出。好。
我来说两句