Performance tips for plugins?

Hi, I made a plugin that drops heads as one of its features, but apparently the part of "adding the skin to the head" has terrible performance for something surprisingly simple.
It's just get the item meta, set the skull owner and put it back. (and put it into the drops list)

I made the report on the fly on my local pc (windows), so it's very likely that it affected the results.

I made this code as an alternative, and while it gets good performance, it kinda looks horrible creating an async task and a sync one inside for each player death.
Not sure if someone has a better tip for this, or if I it will be negligeable once on linux (I won't be able to test this on linux for a couple of days).

    private fun handleHeadDrops(event: PlayerDeathEvent) {
        if (Random.nextDouble() > RootConfig.HEAD.CHANCE) return
        val location = event.player.location
        val world = event.player.world
        Bukkit.getScheduler().runTaskAsynchronously(this.plugin) { _ ->
            val head = ItemStack(Material.PLAYER_HEAD)
            val meta = (head.itemMeta as SkullMeta).apply { owningPlayer = event.player }
            head.itemMeta = meta

            Bukkit.getScheduler().runTask(this.plugin) { _ ->
                val item = world.dropItem(location, head)
            }
        }
    }


This probably will sound silly, but I also don't know how the bukkit scheduler works internally, so idk if it's literally a scheduler, with a separate single thread to run scheduled tasks, or if it creates a different new thread everytime something is scheduled.

Report before: https://spark.lucko.me/wbbIOR4xc0
Report after adding the code above: https://spark.lucko.me/W9JAoVXoR9
spark is a performance profiler for Minecraft clients, servers, and proxies.
spark is a performance profiler for Minecraft clients, servers, and proxies.
Solution
I really like to use coroutines, like this
private fun handleHeadDrops_old(event: PlayerDeathEvent) {
    CoroutineScope(ioDispatcher).launch {
        val head = ItemStack(Material.PLAYER_HEAD)
        val meta = (head.itemMeta as SkullMeta).apply { owningPlayer = event.player }
        head.itemMeta = meta
        withContext(bukkitDispatcher) {
            event.drops.add(head)
        }
    }
}
Was this page helpful?