haxe - Haxe 中使用 Enum 作为 Map 键类型的内存分配问题
问题描述
我关注了一个 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
每次检查枚举数组 from 的值时都会创建一个新数组setBlendMode
,快速添加数万个频繁触发 GC 的变量。
我不熟悉最佳 Haxe 实践,也不知道如何重组。是否有更高效的方式来存储不会产生分配问题的枚举?
编辑:GBlendMode 枚举不能转换为抽象枚举,因为它破坏了其他功能。
编辑2:提出了一个解决方案:https ://github.com/pshtif/Genome2D-ContextFlash/issues/17
解决方案
我看到这看起来像Genome2D 代码。
但是我没有看到GBlendMode
枚举的任何代码——这整个事情都取决于该代码。如果enum GBlendMode
是普通枚举,那么在运行时它们是数组。必须调用 map getter 函数Type.enumParameters
来比较键——我截屏了一个 nodejs 调用堆栈来向自己证明这一点:
但是, ifGBlendMode
是一个抽象枚举 over String
,如下所示:
enum abstract GBlendMode(String) {
var NONE;
var NORMAL;
var ADD;
var MULTIPLY;
var SCREEN;
var ERASE;
}
然后键是简单的字符串,没有枚举比较,也没有创建中间数组。
推荐阅读
- ssis - 无法从命令行构建 SSIS 包:缺少开关参数。/build 开关所需的配置名称
- cryptoapi - 在 coinbase API 上开发第三方交易所
- .htaccess - 使用 Codeigniter 制作的多语言网站。如何将权限设置为一种语言只有一个 IP?
- yocto - Yocto 使用 Multilib 更新到 Sumo 导致 do_image_wic 出错
- javascript - Firefox Quantum Private 浏览器不加载由 javascript 添加的脚本
- python - 在 Mac 的终端中更改用户名命令
- c# - 生成 .xsd 文件的 C# 类
- swift - 更改 UINavigationBar 的分隔符颜色
- xamarin - 如何在 Xamarin Android 中为 Checkbox 添加自定义属性?
- java - 在 Spring Application 中拥有 RestController 和 Controller 的最佳实践