You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 13:55:18