>与其他方法相比,这个脚本的效果如何?
为什么缓冲速度快了?
>如何确定要使用的缓冲区大小?
>这里有人有任何技巧,可以进一步优化这个脚本吗?
(我意识到这可能是CS101,但我是那些被吹嘘的,自学的黑客之一,我希望从这个集体的智慧中受益,谢谢!)
解决方法
作者对这个算法有几个优化.这些都需要对如何使用底层机制(例如,Javascript,cpu,寄存器,缓存,显卡等)有相当深入的了解.我认为他正在做两个关键的优化(剩下的只是结冰):
>缓冲输出
>使用整数数学而不是字符串操作
自从你明确地询问之后,我会尽快讨论缓冲.他使用的整数数学有两个性能优势:整数加法比字符串操作更便宜,并且使用较少的内存.
我不知道JavaScript和Web浏览器如何处理浏览器中的整数转换为显示字形,所以与字符串相比,将整数传递给document.write可能会有一个惩罚.但是,他正在执行(1,000 / 1000)个document.write调用,而1,000 – 1,000个整数.这意味着他正在执行大约3个数量级的操作来形成消息,而不是将其发送到显示器.因此,向document.write发送一个整数与一个字符串的惩罚将超过3个数量级,从而抵消了操纵整数的性能优势.
为什么缓冲速度快了?
其工作原理的具体细节取决于您正在使用的平台,硬件和实现.无论如何,这一切都是为了平衡您的算法与引导资源的瓶颈.
例如,在文件I / O的情况下,缓冲区是有用的,因为它利用旋转磁盘一次只能写入一定量的事实.给它太少的工作,并且不会使用在磁盘旋转时通过主轴头部下方的所有可用位.给它太多,并且您的应用程序将不得不等待(或被放置睡眠),而磁盘完成您的写入时间可以花费下一个记录准备好写作!确定文件I / O的理想缓冲区大小的一些关键因素包括:扇区大小,文件系统块大小,交错,头数,转速和面密度等.
在cpu的情况下,这一切都是为了保持管道充满.如果你给cpu太少的工作,它会花费时间旋转没有OPs,同时等待你的任务.如果给cpu太多,您可能不会将请求发送到可以并行执行的其他资源,例如磁盘或视频卡.这意味着后来的cpu将不得不等待这些返回没有任何事情.在cpu中缓冲的主要因素是将您需要的所有内容(对于cpu)尽可能靠近FPU / ALU.在典型的架构中,这是(按照接近度降低的顺序):寄存器,L1缓存,L2缓存,L3缓存,RAM.
在向屏幕上写入数百万个数字的情况下,它是用您的视频卡在屏幕上绘制多边形.想像这样.让我们说,对于添加的每个新号码,视频卡必须执行100,000次操作,以在屏幕上绘制多边形.在一个极端,如果一次在页面上放1个数字,然后让您的视频卡写出来,您就可以执行1,000个数字,视频卡将进行10 ^ 14次操作 – 100万亿次操作!另一方面,如果你把整个100万的数字一次发送到视频卡,那么只需要10万次操作.最优点是中间的一些.如果你一次这样做,cpu会做一个工作单元,并在GPU更新显示器的同时等待很长时间.如果您首先写入整个1M项目字符串,则cpu在cpu停止运行时不起作用.
你如何确定使用哪个缓冲区大小?
除非您使用特定算法(例如为互联网路由编写数据包路由)定位非常具体且定义良好的平台,否则您通常无法以数学方式确定.通常情况下,您可以从经验上找到.猜一个值,尝试一下,记录结果,然后再选一个.您可以根据您正在管理的瓶颈,对哪里开始和要调查的范围进行一些有根据的猜测.
这里有人有任何技巧,可以进一步优化这个脚本吗?
我不知道这是否可以工作,但是我还没有测试过,但缓冲区的大小通常是2的倍数,因为计算机的下划线是二进制的,字的大小通常是两倍的倍数(但并不总是案件!).例如,64字节比60字节更有可能是最佳的,1024比最有可能超过1000字节.这个问题特有的一个瓶颈是大多数浏览器到目前为止(Google Chrome是我的第一个例外意识到)在与网页渲染机制的其余部分相同的线程中连续执行javascript.这意味着javascript会在缓冲区填充一些工作,然后等待很长时间,直到document.write调用返回.如果javascript作为单独的进程运行,异步运行,像在chrome中,你可能会获得重大的加速.这当然是攻击瓶颈的根源,而不是使用它的算法,但有时这是最好的选择.
不像我想要的那样简洁,但希望这是一个很好的起点.缓冲是计算中各种性能问题的重要概念.了解您的代码使用的基础机制(硬件和软件)对于避免或解决性能问题非常有用.