【问题标题】:Improving Javascript Mandelbrot Plot Performance提高 Javascript Mandelbrot 绘图性能
【发布时间】:2014-09-15 13:37:30
【问题描述】:

我编写了一个 javascript 程序,它用接近边界的正常漂亮颜色绘制 Mandelbrot 集。我正计划下一步添加缩放功能,但它太慢了,不明智。

我在这里发布了代码中最重要的部分:

while (x * x < 2 && y * y < 2 && iteration < max_iteration) {
            xtemp = (x * x) - (y * y) + xcord;
            y = (2 * x * y) + ycord;
            x = xtemp;
            iteration = iteration + 1;
        }

并在此处链接到带有整个页面的 jsfiddle:http://jsfiddle.net/728dn2m0/

我有一些全局变量可以带入主循环,但这会导致对每个像素进行额外的计算。我在另一个 SO question 上读到,1x1 矩形的替代方法是使用图像数据,但性能差异存在争议。另一种可能性是将 while 语句重写为其他条件循环,但我不相信这会给我带来我正在寻找的收益。

我认为自己是一个新手,所以我很高兴听到 cmets 在代码的任何方面,但我真正追求的是能够大幅提高性能的东西。我怀疑我对浏览器中的 javascript 可以管理什么的期望是不合理的,但我希望我错过了一些重要的东西,并且有很大的收获。

提前致谢, 安德鲁

【问题讨论】:

  • 因为严格意义上没有具体问题,所以这个问题可能更适合代码审查。
  • 如果这样会更好,我很乐意移动它。是否可以移动一个问题,或者我需要创建一个新问题并以某种方式删除这个问题?
  • 我的评论更像是一个建议。我检查了 jsfiddle,我对性能有点惊讶;我注意到您的逃生条件不是通常所做的;我认为应该是x*x+y*y&lt;2 而不是x*x &lt; 2 &amp;&amp; y*y&lt;2
  • 我已尝试按照您的建议更改转义条件,但性能没有变化。这来自维基百科:“因为实部或虚部大于 2 的复数不能成为集合的一部分,所以当任一系数超过 2 时,常见的救助措施是逃避。”这就是为什么我将转义条件编码为两个独立的测试。我现在是 GMT+7,所以我要睡觉了,我要再过 17 个小时才能再次回复。我没有失去兴趣!
  • @user1977132: "任一系数超过 2" 为 (x &lt; 2 &amp;&amp; y &lt; 2)

标签: javascript performance fractals mandelbrot


【解决方案1】:

使用 setInterval 作为外部循环结构会减慢计算速度。您将单个像素设置为 5 毫秒,但是整个 Mandelbrot 映射计算可以在 1 秒内完成。因此,对您的函数的一次调用会非常快速地绘制一个像素,然后等待大约 5 毫秒的 99.99%。

我换了

if (m&lt;=(width+1))

while (m&lt;=(width+1))

并删除了 setInterval。

这样,整个计算一步完成,无需刷新屏幕,也无需使用 setInterval 作为外部循环结构。我分叉了你的脚本并修改了它:http://jsfiddle.net/karatedog/2o4gjrv2/6/

在脚本中,我将救助条件从 (x*x &lt; 2 &amp;&amp; y*y &lt; 2) 修改为 (x &lt; 2 &amp;&amp; y &lt; 2),正如我在之前的评论中所建议的那样,并显示了一些隐藏的像素,检查差异!

【讨论】:

  • 你真的修改了救助条件吗?你的小提琴还有 'while (x * x
  • 谢谢,它一定已经恢复到原来的,但现在我修复了它并修改了答案中的 URL。您可以在这个新版本中看到 Mini Mandelbrot
  • 另一条评论,删除间隔对于较小的分辨率来说效果很好,但对于较高的分辨率来说不是一个好的选择,因为在整个集合进行计算时窗口会冻结几秒钟。
  • 很好...改变救助条件意义重大。比较 x^2 是丢弃应该在集合中的点。谢谢!不过,我仍然不相信要删除间隔!请注意,尽管在我的回答中我已经发现了它导致的问题并将其更改为一次只做一列。
  • @user1977132:您使用的浏览器有其自身的局限性,因此浏览器并不是创建大型 Mandelbrot 集的最佳运行环境。我认为只是为了测试 Javascript 而等待 10-20 秒来计算一个集合是没有问题的,如果你进入核心领域(比如 Buddhabrot),你将等待几个小时而不是几秒钟来创建地图,而你将不得不等待使用 C 语言,压缩每个 CPU 周期以更快完成。而且这种计算方法也不是最高效的,更何况 Mandelbrot 计算可以高度并行化。
【解决方案2】:

我确实错过了一些重要的事情。我用来防止页面在绘制集合时挂起的计时器将代码限制为每 5 毫秒一个像素,即每秒 200 个像素。不聪明!

我现在一次绘制一条线,它运行得更好。还不是实时的,但要快得多。

感谢您的想法。我会研究一下逃生条件,看看它应该是什么。

一个带有修改后代码的新 jsfiddle 在这里:http://jsfiddle.net/da1qyh9y/

我添加的 for 语句在这里:

function main_loop() {
if (m<=(width+1)) {
    var n;
    for (n=0; n<height; n=n+1) {

【讨论】:

    猜你喜欢
    • 2013-01-29
    • 1970-01-01
    • 2013-06-28
    • 1970-01-01
    • 2023-04-03
    • 2019-08-23
    • 1970-01-01
    • 2023-03-26
    • 1970-01-01
    相关资源
    最近更新 更多