在JavaScript或许多较小的对象中使用一个大对象会更好吗?

时间:2010-10-12 22:52:17

标签: javascript

我正在编写一个JS库,可以阅读国际象棋游戏,将它们变成可重玩的游戏,在一个网页中可以有很多游戏(一个在自己的div中),我想知道的是 - 考虑性能 - 如果最好有一个大型物体保存所有游戏的所有动作或许多较小的物体,每个物体存储一个游戏的动作。

我意识到这可能是整个优化过程中的一个小点,但它是我现在要解决的问题。

5 个答案:

答案 0 :(得分:26)

唐纳德克努特:“我们应该忘记效率低,大约97%的时间说:过早的优化是所有邪恶的根源”

首先从域建模的角度为游戏设计一个正确且自然的数据模型。

构建软件。

然后,当您处于开发阶段时,分析性能是有意义的,找出一些您喜欢游戏的低性能环境,并在其中进行测试。

你可能会发现你没有任何问题,正如其他人在回答这个问题时所说的那样。

如果您发现问题,请分析您的代码并找出原因。优化您需要的代码。即使您发现了性能问题,只要您设计得很好,它就不太可能是由您的数据模型引起的。

如果数据模型确实是一个性能问题,那么只有在您需要达到所需性能的前提下,才能破坏您的初始设计,记录您所做的妥协以及您必须遵守的原因。

答案 1 :(得分:10)

利用对象的最佳方法是在JavaScript中使用原型模式。这意味着你与对象共享数据,而不是吝啬地说“那是我的!”。

这种模式遍布JavaScript库中。它看起来像这样:

var Template = {
  extend: function () {
    var F = function () {};
    F.prototype = this.prototype;
    var instance = new F();
    instance.mixin.apply(instance, arguments);

    return instance;
  },

  mixin: function (mixins) {
    for (var i = 0, len = arguments.length; i < len; i++) {
      for (var k in arguments[i]) if (arguments[i].hasOwnProperty(k)) {
        this[k] = arguments[i][k];
      }
    }

    return this;
  }
};

这个神奇的类将跨继承链共享数据,并使您的对象模型更简单。什么都不是一个类 - 一切都是对象!这意味着理解JavaScript的细节,以免陷入粘性粘性,但是非常值得。

这意味着当你有:

var Koopa = Template.extend({
  hasShell: true,
  fatalFlaw: 'shell'
});

var Bowser = Koopa.extend({
  fatalFlaw: 'tail'
});

存储的数据如下所示:

+-------------------.   +---------------------.   +---------.
| Bowser             |->| Koopa                |->| Template |
+--------------------+  +----------------------+  +----------+
|fatalFlaw => 'tail' |  | hasShell => true     |  | mixin    |
 `-------------------+  | fatalFlaw => 'shell' |  | extend   |
                         `---------------------+   `---------+

这种设计源于父亲Crockford的prototypal inheritance设计。就像Knuth所说的那样:“过早优化是所有邪恶的根源!”

而且......如果这看起来像是一个偏离主题的答案 - 那是有意的。您应该询问您的设计如何满足您的需求。如果你做得好,那么一切都应该落实到位。如果你认为不够,你可能会得到一些令人讨厌的副作用和臭的代码。帮自己一个忙,想出一个设计,消除你的任何犹豫。浏览器现在比解决国际象棋更复杂和CPU密集的事情!

所以,我的答案是......不要听人们对效率的评价,或者说最好的事情(甚至是我!)。在您的图书馆设计中,做最有意义的事情。现在,你正试图把一个方形钉子塞进一个圆孔里。你需要先确定你的需求是什么,一切都会自然而然地发生。它甚至可能让你感到惊讶!

答案 2 :(得分:4)

小物件是我眼中的首选。

  • 从软件工程的角度来看,使用较小的可组合对象而不是一个整体对象来实现更模块化的设计要好得多。我不是每场比赛都有一个对象,而是将每个动作都表示为一个对象。
  • 最近的JS引擎(如V8)尝试从“类”定义构建类似结构的对象。这种情况发生在幕后,可以快速访问属性。 Google在the design of V8中解释了这一点。从本质上讲,如果你有几个相同类的小实例,它们或多或少是静态的(也就是说,每个类的实例具有相同的属性),V8可以针对这种情况进行优化。

答案 3 :(得分:2)

不要过分担心性能问题。以一种看似自然的方式设计它。显然你不想将所有游戏的所有动作都放在一个对象中,这就违背了面向对象设计的目的。使用第二个选项并为每个游戏设置一个对象。除非你在一个页面上加载数千个游戏,否则你不太可能遇到任何问题。

答案 4 :(得分:1)

我认为这个问题更多的是关于软件设计而不是性能。但是我很高兴你现在正在解决它,避免以后重构。

我认为您应该将每个游戏视为ChessGame对象的实例(div)。这将有助于大部分剩余的开发,如制作自定义库和处理游戏的功能,您也可以在每个游戏中使用线程(谷歌为“网络工作者”),从而提高整体性能。