bot-ssttkkl / nonebot-plugin-mahjong-utils

Nonebot麻将小工具插件,支持手牌分析、番符点数查询
MIT License
7 stars 1 forks source link

支持可选调用mahjong-utils的JVM产物 #13

Closed ssttkkl closed 10 months ago

ssttkkl commented 11 months ago

目前本插件是将mahjong-utils的Native产物以动态库形式进行调用。实测在我的云服务器上对于已摸牌的一向听手牌,每次计算耗时约为1s上下。

测试结果显示Native产物的mahjong-utils在性能上表现太差,计算耗时约为JVM产物的11倍。

image image

测试代码:

package mahjongutils

import mahjongutils.hora.hora
import mahjongutils.models.Tile
import mahjongutils.shanten.furoChanceShanten
import mahjongutils.shanten.shanten
import kotlin.test.Test
import kotlin.time.measureTime

class Benchmark {

    @Test
    fun benchmarkShantenWithGot() {
        val time = measureTime {
            repeat(5) {
                shanten(Tile.parseTiles("12233344455556s"))  // hora
                shanten(Tile.parseTiles("12233344445556s"))  // tenpai
                shanten(Tile.parseTiles("3344z6699p11345s8m"))  // 1-shanten
                shanten(Tile.parseTiles("34568m235p368s")) // 2-shanten
            }
        }
        println("time: $time")
    }

    @Test
    fun benchmarkShantenWithoutGot() {
        val time = measureTime {
            repeat(5) {
                shanten(Tile.parseTiles("1223334445555s"))  // hora
                shanten(Tile.parseTiles("1223334444555s"))  // tenpai
                shanten(Tile.parseTiles("3344z6699p11345s"))  // 1-shanten
                shanten(Tile.parseTiles("34568m235p36s")) // 2-shanten
            }
        }
        println("time: $time")
    }

    @Test
    fun benchmarkFuroShanten() {
        val time = measureTime {
            repeat(20) {
                furoChanceShanten(Tile.parseTiles("3456778m123457p"), Tile.get("7m"))
            }
        }
        println("time: $time")
    }

    @Test
    fun benchmarkHora() {
        val time = measureTime {
            repeat(20) {
                hora(Tile.parseTiles("12233344455556s"), emptyList(), Tile["6s"], true)
            }
        }
        println("time: $time")
    }
}

计划通过配置能够切换使用mahjong-utils的JVM产物或是Native产物。

ssttkkl commented 11 months ago

试了一把graalvm,时间效率和JVM持平,但是只能以executable形式供python调用,而且编译产物有13M

但是kotlinx-serialization无法使用,只能使用jackson进行序列化

ssttkkl commented 10 months ago

webapi (JVM) 通过HTTP进行调用 image

cli (JVM) 直接通过标准输入输出进行调用 image

cli (GraalVM) 直接通过标准输入输出进行调用 image

sharedLibrary (Kotlin/native) 通过动态库形式调用 image

test_bridge还包含启动时间,可以忽略

ssttkkl commented 10 months ago

刚用一天速成的rust重写了DFS部分,结果速度勉强有JVM的一半,和KN持平 不知道是rust的问题还是我的问题,但大概率是我的问题(