Проблема выделения памяти в Haxe с использованием Enum в качестве типа ключа карты

Я слежу за библиотекой 2D GPU и заметил у кого-то проблему с выделением памяти. Array<Map> перечислений вызывается каждый кадр через setBlendMode, в конечном итоге каждый раз вызывается Type.enumParameters Haxe.

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 создает новый массив каждый раз, когда проверяет значения массива enum из setBlendMode, быстро добавляя десятки тысяч переменных, которые часто запускают GC.

Я не знаком с лучшими практиками Haxe и не знаю, как реорганизовать. Есть ли более эффективный способ хранения перечислений, который не создаст проблемы с распределением?

Изменить: Перечисления GBlendMode нельзя преобразовать в абстрактные перечисления, поскольку это нарушает работу других функций.

Изменить 2: было предложено решение: https://github.com/pshtif/Genome2D-ContextFlash/issues/17


person dinorider    schedule 14.07.2020    source источник
comment
Надеюсь, вы не возражаете, что я отредактировал заголовок — проблема не в массиве карт, а в типе ключа карты.   -  person Jeff Ward    schedule 14.07.2020
comment
Это полезно. спасибо!   -  person dinorider    schedule 14.07.2020


Ответы (1)


Я вижу, что это выглядит как код Genome2D< /а>.

Но я не вижу никакого кода для перечисления GBlendMode, и все это зависит от этого кода. Если enum GBlendMode — обычное перечисление, то во время выполнения это массивы. Функция получения карты должна вызывать Type.enumParameters для сравнения ключей — я сделал снимок экрана стека вызовов nodejs, чтобы доказать это самому себе:

введите здесь описание изображения

Однако, если GBlendMode является абстрактным перечислением над String, например так:

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

Тогда ключи представляют собой простые строки, и нет сравнения перечислений, и не создаются промежуточные массивы.

person Jeff Ward    schedule 14.07.2020
comment
Это Геном2Д. Вот исходный класс перечисления: github .com/pshtif/Genome2D-ContextCommon/blob/ Кто-то отправил запрос на включение, но автор отклонил его, поскольку его нельзя было прототипировать: github.com/pshtif/Genome2D-ContextCommon/pull/1 Вызовет ли это ту же проблему или она отличается, потому что это абстрактная строка? - person dinorider; 14.07.2020
comment
Ах, это, вероятно, вызовет ту же проблему... Я не уверен, что такое meta-programmed prototyping, поэтому я не уверен, что могу прокомментировать, как избежать этой проблемы. - person Jeff Ward; 14.07.2020