本帖最后由 Neige 于 2022-6-3 22:59 编辑
今天突然很想知道获取nbt会不会很耗时。
然后测着测着,看着display.Lore,就想知道:
直接从NBT里获取lore,与通过ItemMeta.getLore()相比,哪个更快。
获取一下才发现,哦,直接从NBT里获取的"Lore",是高版本的那种json形式的lore。
将lore中的文本根据颜色(或者说格式)进行切片,将每一段的颜色、加粗等因素,作为对象的属性,存入json。
所以ItemMeta.getLore()要先从nbt里把lore扒出来,再进行解析。
下场就是可老慢,Lore越长越慢,颜色越多越慢。慢得跟蜗牛一样。
但同时我又反应过来,在很多应用情景下,Lore中的"颜色代码",是一种需要排除的东西。
getLore()之后,还得费劲把颜色代码替换掉,非常的麻烦。
于是我思考,直接从nbt中获取display.Lore,对每条Lore进行json解析,再直接获取对象内的文本属性,不管那些颜色属性之类的破玩意儿,是否能更高效地获取Lore呢?
经过测试,答案是可以。
有人可能会说,获取nbt属于草NMS的行为,应该避免这种操作。
但实际上,通过NBT-API或者TabooLib这类前置库,我们可以较为简易,不多思考地直接获取nbt,把草nms和版本适配的重任交给前置库的作者(加油233)。
以使用TabooLib为例(以下为Javascript代码,使用Java或Kotlin可以获得更高效率)。
复制代码通过这种方式,忽视颜色代码获取lore,在物品Lore较为复杂,颜色代码较多的情况下,可以提升一倍以上的效率。
而在颜色代码数量适中的情况下,也能以较小的优势胜过ItemMeta.getLore()。
仅在物品无lore,或者lore极少极简的情况下,会被ItemMeta.getLore()吊打。(指万次40ms与万次1ms)
以上,共勉。
今天突然很想知道获取nbt会不会很耗时。
然后测着测着,看着display.Lore,就想知道:
直接从NBT里获取lore,与通过ItemMeta.getLore()相比,哪个更快。
获取一下才发现,哦,直接从NBT里获取的"Lore",是高版本的那种json形式的lore。
将lore中的文本根据颜色(或者说格式)进行切片,将每一段的颜色、加粗等因素,作为对象的属性,存入json。
所以ItemMeta.getLore()要先从nbt里把lore扒出来,再进行解析。
下场就是可老慢,Lore越长越慢,颜色越多越慢。慢得跟蜗牛一样。
但同时我又反应过来,在很多应用情景下,Lore中的"颜色代码",是一种需要排除的东西。
getLore()之后,还得费劲把颜色代码替换掉,非常的麻烦。
于是我思考,直接从nbt中获取display.Lore,对每条Lore进行json解析,再直接获取对象内的文本属性,不管那些颜色属性之类的破玩意儿,是否能更高效地获取Lore呢?
经过测试,答案是可以。
有人可能会说,获取nbt属于草NMS的行为,应该避免这种操作。
但实际上,通过NBT-API或者TabooLib这类前置库,我们可以较为简易,不多思考地直接获取nbt,把草nms和版本适配的重任交给前置库的作者(加油233)。
以使用TabooLib为例(以下为Javascript代码,使用Java或Kotlin可以获得更高效率)。
- function getNoColorLore(itemStack) {
- const ArrayList = Packages.java.util.ArrayList
- const NMSKt = Packages.com.skillw.pouvoir.taboolib.module.nms.NMSKt
- const lore = new ArrayList()
- const itemTag = NMSKt.getItemTag(itemStack)
-
- if (itemTag.containsKey("display")) {
- const displayTag = itemTag.display
- if (displayTag.containsKey("Lore")) {
- displayTag.Lore.forEach(function(value) {
- const loreList = JSON.parse(value.asString()).extra
- let currentLore = ""
- if (loreList != undefined) {
- for (let index = 0; index < loreList.length; index++) {
- currentLore += loreList[index].text
- }
- }
- lore.add(currentLore)
- })
- }
- }
- return lore
- }
而在颜色代码数量适中的情况下,也能以较小的优势胜过ItemMeta.getLore()。
仅在物品无lore,或者lore极少极简的情况下,会被ItemMeta.getLore()吊打。(指万次40ms与万次1ms)
以上,共勉。
Neige 我的神(复读)
话说为什么要把信息存到lore里面呢?lore应该只是用来显示的吧?内部数据应该作为单独的nbt来储存,反正物品可以任意修改nbt,不会因为被反序列化而消失。
话说为什么要把信息存到lore里面呢?lore应该只是用来显示的吧?内部数据应该作为单独的nbt来储存,反正物品可以任意修改nbt,不会因为被反序列化而消失。
Ph-苯 发表于 2022-6-6 23:25
Neige 我的神(复读)
话说为什么要把信息存到lore里面呢?lore应该只是用来显示的吧?内部数据应该作为单 ...
我个人倾向于将数据存储进自定义NBT,但是这似乎不是大部分人选择的方案。现在仍有大量的人执着于将信息存储于Lore,再根据Lore识别。(当然,这是因为有大量这样的需求)
Neige 发表于 2022-6-7 00:30
我个人倾向于将数据存储进自定义NBT,但是这似乎不是大部分人选择的方案。现在仍有大量的人执着于将信息存 ...
大量这样的需求?
本帖最后由 Neige 于 2022-6-7 10:48 编辑
也不算大量吧,就是很常见。常见于与RPG有关的地方。比如有人要做收购,他们喜欢在lore里写价格;比如有人要物品指令,他们喜欢通过识别lore判断物品;比如有人要属性,他们又喜欢Lore属性……这样干既不安全又性能很差,但是他们习惯这么干。属于一种从低版本一直带过来的操作。不过低版本获取Lore没有这种中间解析一次json的操作,所以性能会好一点,但终究还是慢。毕竟从nbt获取就只需要从map里掏,从lore中解析就是套了一层正则。
Ph-苯 发表于 2022-6-7 10:31
大量这样的需求?
也不算大量吧,就是很常见。常见于与RPG有关的地方。比如有人要做收购,他们喜欢在lore里写价格;比如有人要物品指令,他们喜欢通过识别lore判断物品;比如有人要属性,他们又喜欢Lore属性……这样干既不安全又性能很差,但是他们习惯这么干。属于一种从低版本一直带过来的操作。不过低版本获取Lore没有这种中间解析一次json的操作,所以性能会好一点,但终究还是慢。毕竟从nbt获取就只需要从map里掏,从lore中解析就是套了一层正则。
Neige 发表于 2022-6-7 10:45
也不算大量吧,就是很常见。常见于与RPG有关的地方。比如有人要做收购,他们喜欢在lore里写价格;比如有人 ...
好吧……
只要不是调用得过于频繁,这点性能损失也不足为道了。
为什么我才看到(