【问题标题】:Memory allocation issue in Haxe using Enum as Map key typeHaxe 中使用 Enum 作为 Map 键类型的内存分配问题
【发布时间】:2020-07-14 17:07:27
【问题描述】:

我关注了一个 2D GPU 库,发现有人在内存分配方面遇到了问题。枚举的Array<Map> 每帧通过setBlendMode 调用,最终每次调用Haxe 的Type.enumParameters。

class GBlendModeFunc
{
    private static var blendFactors:Array<Map<GBlendMode,Array<Context3DBlendFactor>>> = [
        [
            GBlendMode.NONE => [Context3DBlendFactor.ONE, Context3DBlendFactor.ZERO],
            GBlendMode.NORMAL => [Context3DBlendFactor.SOURCE_ALPHA, Context3DBlendFactor.ONE_MINUS_SOURCE_ALPHA],
            GBlendMode.ADD => [Context3DBlendFactor.SOURCE_ALPHA, Context3DBlendFactor.DESTINATION_ALPHA],
            GBlendMode.MULTIPLY => [Context3DBlendFactor.DESTINATION_COLOR, Context3DBlendFactor.ONE_MINUS_SOURCE_ALPHA],
            GBlendMode.SCREEN => [Context3DBlendFactor.SOURCE_ALPHA, Context3DBlendFactor.ONE],
            GBlendMode.ERASE => [Context3DBlendFactor.ZERO, Context3DBlendFactor.ONE_MINUS_SOURCE_ALPHA],
        ],
        [
            GBlendMode.NONE => [Context3DBlendFactor.ONE, Context3DBlendFactor.ZERO],
            GBlendMode.NORMAL => [Context3DBlendFactor.ONE, Context3DBlendFactor.ONE_MINUS_SOURCE_ALPHA],
            GBlendMode.ADD => [Context3DBlendFactor.ONE, Context3DBlendFactor.ONE],
            GBlendMode.MULTIPLY => [Context3DBlendFactor.DESTINATION_COLOR, Context3DBlendFactor.ONE_MINUS_SOURCE_ALPHA],
            GBlendMode.SCREEN => [Context3DBlendFactor.ONE, Context3DBlendFactor.ONE_MINUS_SOURCE_COLOR],
            GBlendMode.ERASE => [Context3DBlendFactor.ZERO, Context3DBlendFactor.ONE_MINUS_SOURCE_ALPHA],
        ]
    ];
    
    static public function setBlendMode(p_context:Context3D, p_mode:GBlendMode, p_premultiplied:Bool):Void {
        var p:Int = (p_premultiplied) ? 1 : 0;
        p_context.setBlendFactors(blendFactors[p][p_mode][0], blendFactors[p][p_mode][1]);
    }
}

这里的问题是Type.enumParameters每次从setBlendMode检查枚举数组的值时都会创建一个新的Array,快速添加上万个频繁触发GC的变量。

我不熟悉 Haxe 的最佳实践,也不知道如何重组。有没有更高效的方式来存储不会产生分配问题的枚举?

编辑:GBlendMode enums 无法转换为抽象枚举,因为它破坏了其他函数。

编辑 2: 提出了一个解决方案:https://github.com/pshtif/Genome2D-ContextFlash/issues/17

【问题讨论】:

  • 希望你不介意我编辑了标题——不是地图数组,而是地图键类型导致问题。
  • 这很有帮助。谢谢!

标签: haxe stage3d


【解决方案1】:

我看到这看起来像 Genome2D code。

但我没有看到GBlendMode 枚举的任何代码——而这一切都取决于该代码。如果enum GBlendMode 是一个普通的枚举,那么在运行时它们就是数组。 map getter 函数必须调用 Type.enumParameters 来比较键——我截屏了一个 nodejs 调用堆栈来向自己证明这一点:

然而,如果GBlendMode 是String 之上的抽象枚举,像这样:

enum abstract GBlendMode(String) {
  var NONE;
  var NORMAL;
  var ADD;
  var MULTIPLY;
  var SCREEN;
  var ERASE;
}

那么key就是简单的字符串,没有枚举比较,也没有创建中间数组。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-09-15
  • 2020-07-07
  • 1970-01-01
  • 1970-01-01
  • 2012-05-02
  • 2014-04-24
  • 1970-01-01
相关资源
最近更新 更多