gpt4 book ai didi

javascript - 内存处理与性能

转载 作者:行者123 更新时间:2023-11-29 21:04:42 24 4
gpt4 key购买 nike

我正在构建一个 WebGL 游戏,到目前为止我已经开始调查性能瓶颈。我可以看到在进行 GC 时 FPS 有很多小的下降。因此,我创建了一个小型内存池处理程序。在我开始使用它之后,我仍然看到很多 GC,我可能会怀疑我做错了什么。

我的内存池代码如下所示:

function Memory(Class) {
this.Class = Class;
this.pool = [];

Memory.prototype.size = function() {
return this.pool.length;
};

Memory.prototype.allocate = function() {
if (this.pool.length === 0) {
var x = new this.Class();
if(typeof(x) == "object") {
x.size = 0;
x.push = function(v) { this[this.size++] = v; };
x.pop = function() { return this[--this.size]; };
}
return x;
} else {
return this.pool.pop();
}
};

Memory.prototype.free = function(object) {
if(typeof(object) == "object") {
object.size = 0;
}
this.pool.push(object);
};

Memory.prototype.gc = function() {
this.pool = [];
};
}

然后我像这样使用这个类:

game.mInt = new Memory(Number);
game.mArray = new Memory(Array); // this will have a new push() and size property.
// Allocate an number
var x = game.mInt.allocate();

<do something with it, for loop etc>

// Free variable and push into mInt pool to be reused.
game.mInt.free(x);

我对数组的内存处理是基于使用 myArray.size 而不是 length,它跟踪超维数组(已被重用)中的实际当前数组大小。

所以对于我的实际问题:

使用这种方法可以避免 GC 并在播放期间保留内存。我在函数内部用“var”声明的变量是否仍然是 GC,即使它们从我的 Memory 函数中作为 new Class() 返回?

例子:

var x = game.mInt.allocate();
for(x = 0; x < 100; x++) {
...
}
x = game.mInt.free(x);

由于幕后的某些内存复制,这是否仍会导致“var”的内存垃圾回收? (这会使我的内存处理程序无用)

我的方法是否适合我的情况/对于我试图获得高 FPS 的游戏有意义?

最佳答案

所以你让JS实例化一个新的Object

var x = new this.Class();

然后向该对象添加匿名方法,从而使其成为独一无二的对象

x.push = function...
x.pop = function...

所以现在你使用这个对象的每个地方都更难被 JS 引擎优化,因为它们现在有不同的接口(interface)/隐藏类(相等并不相同)

此外,在您使用这些对象的每个地方,都必须实现额外的类型转换,以将 Number Object 转换回原始类型,并且类型转换不是免费的任何一个。比如,在循环的每次迭代中?甚至多次?

所有这些开销只是为了存储一个 64 位 float ?

game.mInt = new Memory(Number);

并且由于您无法更改内部状态,因此无法更改 Number 对象的值,因此这些值基本上是静态的,就像它们的原始对应物一样。

长话短说:

  • 不要合并原生类型,尤其是原始类型。如今,如果不需要处理意外情况,JS 非常擅长优化代码。令人惊讶的是,具有不同接口(interface)的不同对象必须首先转换为原始值,然后才能使用。

  • 数组大小调整也不是免费的。尽管 JS 对此进行了优化并且通常会预先分配比 Array 可能需要的内存更多的内存,但您仍然可能会达到该限制,因此强制引擎分配新内存,将所有值移动到新内存并释放旧内存。
    我通常对池使用链表。

  • 不要试图把所有东西都放在一起。想一想哪些对象真的可以重复使用,以及您正在努力将它们融入这种“可重复使用性”的叙述中。
    我会说:如果您只需要向对象添加一个新属性(在它被构建之后),那么您需要删除此属性以进行清理,此对象不应被合并。

  • 隐藏类:在谈论 JS 中的优化时,您应该至少在非常基础的水平上了解这个主题
    总结:

    • 不要在构造对象后添加新属性。
    • 为了扩展第一点,不要删除!
    • 添加属性的顺序很重要
    • 改变一个属性的值(甚至是它的类型)没关系!除非我们谈论包含函数(又名方法)的属性。当我们讨论附加到对象的函数时,优化器在这里可能有点挑剔,所以请避免它。
  • 最后但同样重要的是:区分优化对象和“字典”对象。首先在您的概念中,然后在您的代码中。
    尝试将所有内容都放入具有静态接口(interface)的模式中没有任何好处(这是 JS,而不是 Java)。但是静态类型让优化器的工作更轻松。所以把两者组合起来。

关于javascript - 内存处理与性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44588978/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com