Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/40.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Performance Node.js/coffeescript在数学密集型算法上的性能_Performance_Node.js_Coffeescript - Fatal编程技术网

Performance Node.js/coffeescript在数学密集型算法上的性能

Performance Node.js/coffeescript在数学密集型算法上的性能,performance,node.js,coffeescript,Performance,Node.js,Coffeescript,我正在试验node.js来构建一些服务器端逻辑,并实现了coffeescript和Java中描述的diamond square算法的一个版本。鉴于我对node.js和V8性能的赞扬,我希望node.js不会落后于java版本太多 然而,在4096x4096地图上,Java在1s内完成,但node.js/coffeescript在我的机器上占据了20s的时间 这些是我的全部结果。x轴是网格大小。对数和线性图表: 这是因为我的coffeescript实现有问题,还是这只是node.js的本质 咖

我正在试验node.js来构建一些服务器端逻辑,并实现了coffeescript和Java中描述的diamond square算法的一个版本。鉴于我对node.js和V8性能的赞扬,我希望node.js不会落后于java版本太多

然而,在4096x4096地图上,Java在1s内完成,但node.js/coffeescript在我的机器上占据了20s的时间

这些是我的全部结果。x轴是网格大小。对数和线性图表:

这是因为我的coffeescript实现有问题,还是这只是node.js的本质

咖啡脚本
genHeightField=(sz)->
timeStart=新日期()
数据大小=sz
种子=1000.0
数据=新数组()
iters=0
#预热阵列,告诉js引擎这些是密集阵列
#不过,在node.js上运行时似乎会产生不可忽略的效果
对于[0…数据大小]中的行
数据[行]=新数组();
对于[0…数据大小]中的列
数据[行][cols]=0
数据[0][0]=数据[0][data_SIZE-1]=数据[data_SIZE-1][0]=
数据[数据大小-1][数据大小-1]=种子;
h=500.0
边长=数据大小-1
而边长>=2
半边=边长/2
对于x英寸[0…数据大小-1],按边长
对于[0…数据大小-1]中的y,按边长
平均值=数据[x][y]+
数据[x+边长][y]+
数据[x][y+边长]+
数据[x+边长][y+边长]
平均值/=4.0;
数据[x+半边][y+半边]=
平均+数学随机()*(2*h)-h;
iters++
#console.log“A:”+x+“,“+y”
对于x英寸[0…数据大小-1],按半边
y=(x+半边)%sideLength
而y
JAVA
import java.util.Random;
类Gen{
公共静态void main(字符串参数[]){
身高(256+1);
身高(512+1);
基因高度(1024+1);
genHeight(2048+1);
身高(4096+1);
}
公共静态高度(内部sz){
long timeStart=System.currentTimeMillis();
int-iters=0;
最终整数数据_SIZE=sz;
最终双种子=1000.0;
双精度[]数据=新的双精度[数据大小][数据大小];
数据[0][0]=数据[0][data_SIZE-1]=数据[data_SIZE-1][0]=
数据[数据大小-1][数据大小-1]=种子;
双h=500.0;
随机r=新随机();
对于(int sideLength=DATA_SIZE-1;
边长>=2;
边长/=2,h/=2.0){
内半边=边长/2;

对于(int x=0;x暂时不要考虑Coffeescript,因为这不是问题的根源。当node运行它时,该代码只会被写入常规的旧javascript

就像其他javascript环境一样,node是单线程的。V8引擎速度非常快,但对于某些类型的应用程序,您可能无法超过jvm的速度

首先,我建议在转到CS之前,尝试直接在js中修改菱形算法。看看你能做什么样的速度优化

事实上,我现在对这个问题也有点感兴趣,我想看看如何做

编辑#2这是我的第二次重写,进行了一些优化,例如预填充数据数组。虽然速度没有明显加快,但代码更干净了一点

var makegrid = function(size){
    size++; //increment by 1

    var grid = [];
        grid.length = size,
        gsize = size-1; //frequently used value in later calculations.

    //setup grid array
    var len = size;
    while(len--){
        grid[len] = (new Array(size+1).join(0).split('')); //creates an array of length "size" where each index === 0
    }

    //populate four corners of the grid
    grid[0][0] = grid[gsize][0] = grid[0][gsize] = grid[gsize][gsize] = corner_vals;

    var side_length = gsize;

    while(side_length >= 2){
        var half_side = Math.floor(side_length / 2);

        //generate new square values
        for(var x=0; x<gsize; x += side_length){
            for(var y=0; y<gsize; y += side_length){

                //calculate average of existing corners            
                var avg = ((grid[x][y] + grid[x+side_length][y] + grid[x][y+side_length] + grid[x+side_length][y+side_length]) / 4) + (Math.random() * (2*height_range - height_range));

                //calculate random value for avg for center point
                grid[x+half_side][y+half_side] = Math.floor(avg);

            }
        }

        //generate diamond values
        for(var x=0; x<gsize; x+= half_side){
            for(var y=(x+half_side)%side_length; y<gsize; y+= side_length){

                var avg = Math.floor( ((grid[(x-half_side+gsize)%gsize][y] + grid[(x+half_side)%gsize][y] + grid[x][(y+half_side)%gsize] + grid[x][(y-half_side+gsize)%gsize]) / 4) + (Math.random() * (2*height_range - height_range)) );

                grid[x][y] = avg;

                if( x === 0) grid[gsize][y] = avg;
                if( y === 0) grid[x][gsize] = avg;
            }
        }

        side_length /= 2;
        height_range /= 2;
    }

    return grid;
}

makegrid(256)
makegrid(512)
makegrid(1024)
makegrid(2048)
makegrid(4096)
var makegrid=函数(大小){
size++;//增加1
var网格=[];
网格长度=大小,
gsize=size-1;//在以后的计算中经常使用的值。
//设置网格阵列
var len=大小;
而(len--){
grid[len]=(新数组(大小+1).join(0).split(“”));//创建一个长度为“size”的数组,其中每个索引===0
}
//填充网格的四个角
网格[0][0]=网格[gsize][0]=网格[0][gsize]=网格[gsize][gsize]=角值;
var side_length=gsize;
而(边长>=2){
var half_side=数学楼层(边长/2);
//生成新的平方值

对于(var x=0;x如果你想在这样的算法中寻找性能,那么coffee/js和Java都是错误的语言。Javascript对于这样的问题尤其糟糕,因为它没有数组类型-数组只是散列映射,其中键必须是整数,这显然不会像真正的数组那么快ant将用C编写此算法,并从节点调用该算法(请参阅)。除非你真的擅长优化机器代码,否则好的C语言很容易超越任何其他语言。

正如其他回答者所指出的,JavaScript的数组是你正在执行的操作类型的主要性能瓶颈。因为它们是动态的,访问元素自然要比使用Java的静态语言慢得多数组

好消息是,JavaScript中的静态类型数组有了一个新的标准,一些浏览器已经支持了该标准。虽然Node本身还不支持该标准,但您可以通过一个库轻松地添加它们:

安装后
var makegrid = function(size){
    size++; //increment by 1

    var grid = [];
        grid.length = size,
        gsize = size-1; //frequently used value in later calculations.

    //setup grid array
    var len = size;
    while(len--){
        grid[len] = (new Array(size+1).join(0).split('')); //creates an array of length "size" where each index === 0
    }

    //populate four corners of the grid
    grid[0][0] = grid[gsize][0] = grid[0][gsize] = grid[gsize][gsize] = corner_vals;

    var side_length = gsize;

    while(side_length >= 2){
        var half_side = Math.floor(side_length / 2);

        //generate new square values
        for(var x=0; x<gsize; x += side_length){
            for(var y=0; y<gsize; y += side_length){

                //calculate average of existing corners            
                var avg = ((grid[x][y] + grid[x+side_length][y] + grid[x][y+side_length] + grid[x+side_length][y+side_length]) / 4) + (Math.random() * (2*height_range - height_range));

                //calculate random value for avg for center point
                grid[x+half_side][y+half_side] = Math.floor(avg);

            }
        }

        //generate diamond values
        for(var x=0; x<gsize; x+= half_side){
            for(var y=(x+half_side)%side_length; y<gsize; y+= side_length){

                var avg = Math.floor( ((grid[(x-half_side+gsize)%gsize][y] + grid[(x+half_side)%gsize][y] + grid[x][(y+half_side)%gsize] + grid[x][(y-half_side+gsize)%gsize]) / 4) + (Math.random() * (2*height_range - height_range)) );

                grid[x][y] = avg;

                if( x === 0) grid[gsize][y] = avg;
                if( y === 0) grid[x][gsize] = avg;
            }
        }

        side_length /= 2;
        height_range /= 2;
    }

    return grid;
}

makegrid(256)
makegrid(512)
makegrid(1024)
makegrid(2048)
makegrid(4096)
{Float32Array} = require 'typed-array'

genHeightField = (sz) ->
    timeStart = new Date()
    DATA_SIZE = sz
    SEED = 1000.0
    iters = 0

    # Initialize 2D array of floats
    data = new Array(DATA_SIZE)
    for rows in [0...DATA_SIZE]
      data[rows] = new Float32Array(DATA_SIZE)
      for cols in [0...DATA_SIZE]
          data[rows][cols] = 0

    # The rest is the same...
17
75
417
1376
5461
19
47
215
855
3452