Skript: Inventory effects & expressions are really slow in 1.12

Created on 5 Aug 2017  路  7Comments  路  Source: SkriptLang/Skript

Hello again.
I was trying to make a kits script. However, I noticed that giving items is working insanely slowly in the new versions (5 ms to give 5 items). You can even feel that there's a big delay between each item appearing in your inventory

Here's how I am doing it:

command /kit [<text>]:
    permission: itempackage.kit
    permission message: {@P}
    trigger:
        set {_s} to size of {packages::package::%arg 1%::*}
        loop 36 times:
            if {_n} = {_s}:
                stop loop
            slot loop-number - 1 of player = air
            add 1 to {_n}
            set {_slots::%{_n}%} to loop-number - 1
        loop {packages::package::%arg 1%::*}:
            set slot {_slots::%loop-index%} of player to loop-value

Takes 1~1.5 ms to run.

However, simply giving the items is laggy:

command /kit [<text>]:
    permission: itempackage.kit
    permission message: {@P}
    trigger:
        loop {packages::package::%arg 1%::*}:
            give loop-value to player

Takes 5 ms.

Hope you can fix this.
Thanks!

bug needs-testing medium

Most helpful comment

Made a full test here:

Insanely slow:

command /test0:
    trigger:
        remove all items from player's inventory

[15:02:38 INFO]: [Skript] # /test0
[15:02:38 INFO]: [Skript] # test0 took 12.803814 milliseconds

Reasonable, but slower than manual clearing

command /test1:
    trigger:    
        clear player's inventory

[15:03:24 INFO]: [Skript] # /test1
[15:03:24 INFO]: [Skript] # test1 took 1.709404 milliseconds

I think it's slow for just 4 items

command /test3:
    trigger:
        set {_a::*} to diamond sword, iron sword, iron axe and stone shovel
        loop {_a::*}:
            give loop-value to player

[15:03:54 INFO]: [Skript] # /test3
[15:03:54 INFO]: [Skript] # test3 took 1.852104 milliseconds

Most performance-friendly inventory clearing:

command /test4:
    trigger:
        loop all items in player's inventory:
            clear loop-item

[15:04:27 INFO]: [Skript] # /test4
[15:04:27 INFO]: [Skript] # test4 took 0.475441 milliseconds

0.6 ms for one item.

command /test5:
    trigger:
        set {_i} to diamond sword of sharpness 5, knockback 2 named "TEST" with lore "HEY"
        give {_i} to player

[15:10:58 INFO]: [Skript] # /test5
[15:10:58 INFO]: [Skript] # test5 took 0.645621 milliseconds

Not bad, but could be better I think.

command /test6:
    trigger:
        if player can hold 64 stone:
            broadcast "CAN HOLD STONE"

[15:11:38 INFO]: [Skript] # /test6
[15:11:38 INFO]: CAN HOLD STONE
[15:11:38 INFO]: [Skript] # test6 took 0.533713 milliseconds

Faster than looping, so fine

[15:12:22 INFO]: [Skript] # /test7
[15:12:22 INFO]: HAS DIAMOND SWORD
[15:12:22 INFO]: [Skript] # test7 took 0.455576 milliseconds
command /test8:
    trigger:
        broadcast "%number of diamond sword in player's inventory%"

[15:14:56 INFO]: [Skript] # /test8
[15:14:56 INFO]: 5
[15:14:56 INFO]: [Skript] # test8 took 0.404589 milliseconds
command /test9:
    trigger:
        remove 64 diamond from player's inventory

[15:17:53 INFO]: [Skript] # /test9
[15:17:53 INFO]: [Skript] # test9 took 0.372805 milliseconds

I am comparing only player's tool, I don't think it should take 0.5 ms.

command /test10:
    trigger:
        tool = diamond sword
        broadcast "IS DIAMOND SWORD"

[15:20:04 INFO]: [Skript] # /test10
[15:20:04 INFO]: IS DIAMOND SWORD
[15:20:04 INFO]: [Skript] # test10 took 0.439022 milliseconds

Another thing:
If I give this sword to player give diamond sword of sharpness 5, knockback 2 named "TEST" with lore "HEY" to player, then use player has diamond sword of sharpness 5, knockback 2 named "TEST" it won't work, because the lore doesn't match.

The same works for NBT, if I add ANYTHING different in NBT, it won't match the item, even though it matches the conditions.

Using only name and enchantments, it'll match normally.

inventory of %player% is empty doesn't work too.

That's it basically.

All 7 comments

Hmm, sounds like a possible bug. Could you check what happens if you just give player same item in loop, without using loop-value. Does it cause performance issues?

Made a full test here:

Insanely slow:

command /test0:
    trigger:
        remove all items from player's inventory

[15:02:38 INFO]: [Skript] # /test0
[15:02:38 INFO]: [Skript] # test0 took 12.803814 milliseconds

Reasonable, but slower than manual clearing

command /test1:
    trigger:    
        clear player's inventory

[15:03:24 INFO]: [Skript] # /test1
[15:03:24 INFO]: [Skript] # test1 took 1.709404 milliseconds

I think it's slow for just 4 items

command /test3:
    trigger:
        set {_a::*} to diamond sword, iron sword, iron axe and stone shovel
        loop {_a::*}:
            give loop-value to player

[15:03:54 INFO]: [Skript] # /test3
[15:03:54 INFO]: [Skript] # test3 took 1.852104 milliseconds

Most performance-friendly inventory clearing:

command /test4:
    trigger:
        loop all items in player's inventory:
            clear loop-item

[15:04:27 INFO]: [Skript] # /test4
[15:04:27 INFO]: [Skript] # test4 took 0.475441 milliseconds

0.6 ms for one item.

command /test5:
    trigger:
        set {_i} to diamond sword of sharpness 5, knockback 2 named "TEST" with lore "HEY"
        give {_i} to player

[15:10:58 INFO]: [Skript] # /test5
[15:10:58 INFO]: [Skript] # test5 took 0.645621 milliseconds

Not bad, but could be better I think.

command /test6:
    trigger:
        if player can hold 64 stone:
            broadcast "CAN HOLD STONE"

[15:11:38 INFO]: [Skript] # /test6
[15:11:38 INFO]: CAN HOLD STONE
[15:11:38 INFO]: [Skript] # test6 took 0.533713 milliseconds

Faster than looping, so fine

[15:12:22 INFO]: [Skript] # /test7
[15:12:22 INFO]: HAS DIAMOND SWORD
[15:12:22 INFO]: [Skript] # test7 took 0.455576 milliseconds
command /test8:
    trigger:
        broadcast "%number of diamond sword in player's inventory%"

[15:14:56 INFO]: [Skript] # /test8
[15:14:56 INFO]: 5
[15:14:56 INFO]: [Skript] # test8 took 0.404589 milliseconds
command /test9:
    trigger:
        remove 64 diamond from player's inventory

[15:17:53 INFO]: [Skript] # /test9
[15:17:53 INFO]: [Skript] # test9 took 0.372805 milliseconds

I am comparing only player's tool, I don't think it should take 0.5 ms.

command /test10:
    trigger:
        tool = diamond sword
        broadcast "IS DIAMOND SWORD"

[15:20:04 INFO]: [Skript] # /test10
[15:20:04 INFO]: IS DIAMOND SWORD
[15:20:04 INFO]: [Skript] # test10 took 0.439022 milliseconds

Another thing:
If I give this sword to player give diamond sword of sharpness 5, knockback 2 named "TEST" with lore "HEY" to player, then use player has diamond sword of sharpness 5, knockback 2 named "TEST" it won't work, because the lore doesn't match.

The same works for NBT, if I add ANYTHING different in NBT, it won't match the item, even though it matches the conditions.

Using only name and enchantments, it'll match normally.

inventory of %player% is empty doesn't work too.

That's it basically.

I will take look at performance issues. About your "another thing", are you sure it is new with latest release? Sounds like old "feature" for me.

http://prntscr.com/g4sg78

command /test11:
    trigger:
        give a diamond sword of sharpness 5, knockback 2 named "TEST" with lore "HEY" to player
        if player has diamond sword of sharpness 5, knockback 2 named "TEST":
            send "Indeed"
        else:
            send "Negative"

That's because the diamond sword of sharpness 5, knockback 2 named "TEST" isn't a part of condition, so it creates an item and pass to the condition, and the condition check if it has that item, not similiar item.

@TrademarkTM Is this still an issue? Bensku has changed the Slot system recently

The changes are not relevant for this issue.

Was this page helpful?
0 / 5 - 0 ratings