Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/422.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
在Javascript中创建数百万个对象_Javascript_Object - Fatal编程技术网

在Javascript中创建数百万个对象

在Javascript中创建数百万个对象,javascript,object,Javascript,Object,让我首先说,这不是我通常做的事情,但出于好奇,我会看看是否有人对如何处理这样的问题有好的想法 我正在开发的应用程序是一个模拟的游戏示例,让我们用Monty Hall问题做一个交易 我不会详细介绍我的实现,但它或多或少允许用户输入他们想要模拟的游戏数量,然后如果关闭某个选项,这些x游戏的玩家将不会切换他们的选择,而如果打开,他们将切换游戏的每个实例 我的对象生成器如下所示: const game = function(){ this[0] = null; this[1] = nul

让我首先说,这不是我通常做的事情,但出于好奇,我会看看是否有人对如何处理这样的问题有好的想法

我正在开发的应用程序是一个模拟的游戏示例,让我们用Monty Hall问题做一个交易

我不会详细介绍我的实现,但它或多或少允许用户输入他们想要模拟的游戏数量,然后如果关闭某个选项,这些x游戏的玩家将不会切换他们的选择,而如果打开,他们将切换游戏的每个实例

我的对象生成器如下所示:

const game = function(){
    this[0] = null;
    this[1] = null;
    this[2] = null;
    this.pick = Math.floor(Math.random() * 3);
    this.correctpick = Math.floor(Math.random() * 3);
    this[this.correctpick] = 1;
    for (let i=0; i<3; i++){
        if ((this[i] !== 1) && (i !== this.pick)){
            this.eliminated = i;
            break;
        }
    }
}

const games = arg => {
    let ret = [];
    for(let i=0; i<arg; i++){
        ret.push(new game);
    }
    return ret;
}
[
  {
    "0": 1,
    "1": null,
    "2": null,
    "pick": 2,
    "correctpick": 0,
    "eliminated": 1
  },
  {
    "0": null,
    "1": null,
    "2": 1,
    "pick": 2,
    "correctpick": 2,
    "eliminated": 0
  }
]
尽管游戏的构造函数看起来很邋遢,但原因是我已经将其重构为具有尽可能少的函数调用,现在我实际上只调用数学函数,在当前时间,我删除了使代码更易于阅读的任何辅助函数,以选择性能

这个应用程序既可以在浏览器中运行,也可以在跨平台的节点中运行,但我已经将用户可以进入游戏功能的arg限制为500万。如果超过此时间,进程或窗口将冻结超过几秒钟,甚至可能崩溃

如果用户给出了一个巨大的数字,我还能做些什么来提高性能吗?另外,如果您需要更多信息,我将很乐意提供


谢谢

明显的性能优化是根本不创建和存储500万个对象,从而减轻内存压力。相反,您只需要在需要时动态创建对象,然后立即将它们扔掉。我不确定你的应用程序是做什么的,但听起来你想在使用不同选项评估结果时重复使用相同的游戏实例。在这种情况下,你当然需要存储它们,但我建议重新设计,并考虑立即评估每一个游戏的所有可能的选项,只积累每一个选项的选择结果,但不能保持所有游戏在内存中。 除此之外,我建议简化一点:

您可以完全删除该循环,并使用一些巧妙的算法来查找已消除的选项:this.remelected=this.pick==this.correctpick?+!this.pick:3-this.pick-this.correctpick;。或者使用一个简单的查找表this.implemented=[1,2,1,2,0,0,1,0,0][this.pick*3+this.correctpick]。 我会避免将数组元素的类型从空引用更改为1个数字。只需将它们保留为整数,并用0初始化元素即可。 不要在对象中存储6个完全冗余的属性。你只需要其中的两个:pick和correctpick——当你需要的时候,其他的一切都可以通过它们在飞行中计算出来。只有在计算量大且结果经常使用的情况下,预计算和存储它才是有利的。这两种情况都不是,但是保持低内存占用很重要,但是,不要对此期望太高。
不确定您的实现,但您真的需要阵列吗

只使用结果查看代码段怎么样

如果让你担心的是它阻塞了浏览器,那么将工作委托给一个管理员可能是解决问题的方法:请参阅此代码段的web worker版本

=> { document.querySelectordoit .addEventListenerclick、playMontyHall.HandlerRequest; 函数playMontyHall{ const result=document.querySelectorresult; 常量计时=document.querySelectortiming; const nOfGames=document.querySelectornGames; const switchDoors=document.querySelectorswitchyn; //创建一个游戏 const game=doSwitch=>{ 常数门=[0,1,2]; const pick=Math.floorMath.random*3; const correctPick=Math.floorMath.random*3; 已消除常数=doors.filterv=>v!==pick&&v!==correctPick[0]; 返回{ correctpick:correctpick, 拾取:doSwitch?doors.filterv=>v!==拾取和&v!==已消除[0]:拾取, 淘汰:淘汰,, }; }; const getWinner=game=>~~game.correctpick===game.pick; //使用生成器函数求和获胜 常数winningGenerator=函数*doSwitch,n{ 让wins=0; 而n-{ wins+=getWinnergamedoSwitch; 产量赢; } }; //计算成功游戏的数量 const calculateGames=nGames,switchAlways=>{ const funNGames=Winning Generators SwitchAlways,nGames; 设numberOfWins=0; 而nGames-{ numberOfWins=funNGames.next.value; } 返回个数; } 常量清理=播放=>{ result.textContent= 播放…可能会持续几秒钟; timening.textContent=; SetTimeOutput布局,0; }; 常量报告=结果=>{ timing.textContent=`这花了${ performance.now-results.startTime .toFixed3}毫秒`; result.innerHTML= `${!results.switchAlways?从不s:始终s}切换门: ${results.winners}在${results.nGames}游戏中获胜 ${results.winners/+results.nGames*100.toFixed2}%`; }; //公共手柄按钮点击 功能点击手柄{ 清理=>{ 常数nGames=nOfGames.value | | 5000000; const switchAlways=开关门。已检查; 报告{ switchAlways:switchAlways, 开始时间:表演,现在, 赢家:计算平均时间,切换始终, nGames:nGames }; }; } 返回{ HandlerRequest:单击句柄 }; } }; 身体{ 边缘:2米; 字体:普通12px/15px verdana,arial; } 时机{ 颜色:红色; } N游戏

一定要把门关上


是否有可能将它们的属性压缩到不同的数组/映射中?如果您不使用兼容的字符串,请不要使用JSON这个术语。此结构会生成一些JSON数据。。。扩大尼娜的评论:不,没有。它生成一些JavaScript对象。JSON是用于数据交换的文本表示法。如果您处理的是JavaScript源代码,而不是字符串,那么您就不是在处理JSON。很抱歉,稍后在我的代码中,我将使用JSON.stringifysimulation,其中simulation就是您上面看到的数据结构。@simon为什么不使用我???感谢您的帮助。我试着换到你推荐的最上面一行,结果sim卡坏了。它不是在做同样的事情。不过,如果可以提高性能,我将使用您的想法将数值设置为0作为默认值。哎呀,我错过了选择正确的选项,它有点复杂,但仍然不需要循环。然而,蒙蒂·霍尔的规则不是说如果选择正确,必须随机选择被淘汰的选项吗?您总是删除两个可用选项中的第一个。我删除循环发现的第一个未拾取且不包含奖品的选项。如果此[i]!=1&&this.pick!==我{@simon是的,我认为第一个是错误的。你需要随机选择一个满足条件的,可能有1或2个值可以消除。我唯一需要重新随机选择移除室的时间是在用户正确选择的情况下,这几乎没有33%的时间发生。这是一个有趣的项目,而且我一直很怀疑,直到我第一次看到我的代码在100多场比赛中运行,如果你切换,你的几率会上升到66%:这是一个了不起的解决方案!我会看看你的代码谢谢!我把我的答案改成了你的。你这里有一些不可思议的东西Kooilnc,谢谢!好吧,你现在让我迷上了web/服务人员。谢谢非常感谢你。我只有一个简单的问题要问你。你的setTimeoutplayout,0在清理中的意义是什么?唯一一件事我在你的代码中没有完全理解。再次感谢你!:嗨@simon,很高兴我能帮上忙。setTimeout的意义是能够清理屏幕。没有它,UI在完成播放后会重写。这是一个b这是一个技巧。附录:web工作者代码中不需要setTimeout:您可以使用工作者消息处理程序清理屏幕,因为工作者是不同的线程。我调整了JSFIDLE代码。