Godot 4.4类型化Dictionary性能测试疑问:键值类型影响效率?
Godot 4.4类型化Dictionary性能测试疑问解析
1. 为何[String, int]字典赋值慢于[int, String]?
Godot的Dictionary底层基于哈希表实现,键的哈希计算与匹配是字典操作的核心开销来源:
- int作为键时,哈希值可直接通过数值快速生成,键的比较也是简单的数值对比,几乎无额外开销;
- 而String作为键时,不仅要为每个
str(i)创建临时字符串对象,还要遍历字符串内容计算哈希值——这一过程的开销远大于int的哈希计算。同时字符串对象的创建与销毁也会带来额外的内存管理开销,最终导致整体耗时更高。
2. 类型化Dictionary为何未体现效率优势?
类型化Dictionary的设计优势是在复杂场景下减少运行时类型检查与转换开销,但你的测试场景存在几个限制因素:
- 非类型化Dictionary已被优化:GDScript的虚拟机会做局部类型推断,当你连续给非类型化字典赋值固定类型的键值时,虚拟机会缓存类型信息,跳过重复的类型检查,此时两者的性能差异被抹平;
- 类型化字典的额外校验:类型化Dictionary每次操作都要强制验证键值是否符合声明类型,这部分校验逻辑在简单赋值场景中占比更高,反而导致耗时略增;
- 计时精度不足:你使用的
Time.get_unix_time_from_system()仅能精确到秒,测试结果的误差较大,无法准确反映微秒级的性能差异,建议改用Time.get_ticks_usec()(微秒级)计时。
3. 是否因程序规模小,编译器自行推断了类型?
是的,这是核心原因之一。GDScript编译器与虚拟机支持局部类型推断,当代码中存在连续、固定类型的赋值操作时,虚拟机会自动推断出非类型化字典的键值类型,跳过后续的类型检查步骤,让非类型化字典的性能接近甚至超过类型化字典。
只有在复杂场景下——比如函数间传递字典、混合赋值不同类型的键值、大量读写混合操作——类型化Dictionary的优势才会显现:它能在编译期提前做类型校验,避免运行时类型错误,同时减少虚拟机的类型推断开销。
优化后的测试代码示例
func _ready() -> void: var typedDict: Dictionary[String, int] = {} var regDict: Dictionary = {} var regVar = {} # 微秒级计时更精准 var startTimeTyped: int = Time.get_ticks_usec() for i in range(300000): var key = str(i) typedDict[key] = i print("Typed Dict [String, int]: ", (Time.get_ticks_usec() - startTimeTyped) / 1000000.0, "s") var startTimeReg: int = Time.get_ticks_usec() for i in range(300000): var key = str(i) regDict[key] = i print("Regular Dict: ", (Time.get_ticks_usec() - startTimeReg) / 1000000.0, "s") var startTimeVar: int = Time.get_ticks_usec() for i in range(300000): var key = str(i) regVar[key] = i print("Variant Dict: ", (Time.get_ticks_usec() - startTimeVar) / 1000000.0, "s") # 测试[int, String]类型 var typedDict2: Dictionary[int, String] = {} var startTimeTyped2: int = Time.get_ticks_usec() for i in range(300000): var val = str(i) typedDict2[i] = val print("Typed Dict [int, String]: ", (Time.get_ticks_usec() - startTimeTyped2) / 1000000.0, "s")
内容的提问来源于stack exchange,提问作者Frasher Gray
相关产品推荐
相关产品推荐

