官方的更新日志中提到宏函数存在缓存机制。Slicedlime的快照视频也有提到这一机制。翻看源码得知,缓存的解析后的宏函数会存在一个哈希表里,以传入参数组成的字符串列表作为键。每当有宏函数的参数集在表中没有对应的键时,就会被放进这张表里。同时,表中最多可以缓存8个解析后的宏函数。超过上限时,最先被放进表里的函数会被先被移除。
针对缓存机制准备的测试函数:
另外准备了一份测试函数,用来验证缓存机制对性能的优化:
(相关资料图)
高频执行函数test:data_default_test(左)、test:data_macro_test(中)、test:data_macro_test_cache(右)的结果(tps数据看上去比较直观就不放debug日志了):
结论:执行不在缓存中的宏函数、解析宏命令的开销比对storage进行简单的nbt数据编辑操作要大,但差得并不是太多,不像nbt操作与记分板操作之间存在几个量级的差距。这个微妙的差距使得实际应用的过程中,在一些功能实现上使用宏的新方法与不使用宏的旧方法性能之间的差距非常值得斟酌,如uuid匹配与json文本合并,运用宏命令往往只是减少了几条data命令的使用。
1. json文本合并之前进行json文本合并的方法通常是将两段json文本存在storage里放在木牌上解析一次拿出合并的结果,而引入宏命令后只需要一条命令就刻印完成合并工作。测试函数:
高频执行函数generic:text/combine/json_with_format/new_test(左)、generic:text/combine/json_with_format/old_test(右)的结果:
结论:使用宏函数的json文本合并性能更好(注:同时在宏函数合并的结果当中json文本并未被解析成使用了extra组件的形式)。
2. UUID匹配
之前UUID匹配的方法通常是将代查找实体的UUID存进掉落物的Thrower里,再通过on origin改变执行者。引入了宏函数可直接对传入的UUID所指的实体进行操作。测试函数:
高频执行函数generic:entity/generic/get_with_uuid/new_test(左)、generic:entity/generic/get_with_uuid/old_test(右)的结果:
结论:使用宏函数的uuid搜索稍好性能稍好(注:其实这里两种方法输入的UUID的形式是不同的,不过实体16进制的UUID可以转化外手动找个地方存着,所以在这里开销忽略不计)。 欢迎补充更多实例!
关键词: