ลอง Kotlin: กรณีโปรแกรมตัดคำ

ตัดคำเขียนด้วย Kotlin เกือบ ๆ หมดครับ มีส่วนอ่านไฟล์กับจัดการพวก command line argument ใช้ Clojure เพราะว่าไม่น่าจะมีผลอะไรกับความเร็วมาก

ชื่อโปรแกรมนึกไม่ออกจะเอาชื่อสถานที่ในระยองมาตั้งก็ยกมาแทบหมดแล้ว เห็นมี LexTo บน JVM ก็เลยตั้งชื่ออันนี้ว่า yaito แล้วกัน ในการพัฒนาก็ไม่ได้เกี่ยวอะไรกันเลย; yaito นี่พยายามเอา wordcut-py กับ wordcut-clj ยำกัน

ตอนใช้จริงๆ โหลด yaito-cliก็พอ ถ้า code สำคัญ ๆ อยู่ที่ yaito

หลังจากลองเขียนไปก็มีประเด็นมาเล่าเกี่ยวกับ Kotlin อยู่บ้าง

  • เขียนแบบข้างล่างเจ๊ง
    if (link?.isBetterThan(selectedLink)) {
    

    เพราะว่าเขียนข้างบนถ้า link เป็น null แล้ว ?.isBetterThan ก็จะ ตอบ null มาด้วยแล้ว แต่ if ต้องการ true/false

    ท่าแก้ท่านหึ่งคือเขียนแบบนี้ เพราะว่าผมมั่นใจว่า link ไม่เป็น null แน่ ๆ

    if (link?.isBetterThan(selectedLink)!!) {
    

    แต่ว่าใช้ link!!.isBetterThan แต่แรกไปเลยดีกว่า ?

  • เวลามี val path: Array ใน data class แล้วมันเตือน จริง ๆ คงเตือน array ทั้งหมด แต่ผมยังงง ๆ อยู่ว่าเดือนทำไม
  • ใน PatLinkBuilder ทีแรกเขียนแบบนี้
     var s = null
    

    แล้วพอพยายามเขียนให้ s = context.i เจ๊งเลย ต้องเปลี่ยนไปแบบข้างล่าง

     var s: Int? = null
    

    ก็เป็นอันใช้ได้

  • ลองเขียนแบบ
    open class PatLinkBuilder(val isAcceptable) : LinkBuilder
    

    แล้วเอาไปใช้แบบนี้

    class SpaceLinkBuilder: PatLinkBuilder( { it == ' '} )
    

    พบว่าเจ๊งต้องระบบ type ของ isAcceptable ถึงใช้ไ้ด

    open class PatLinkBuilder(val isAcceptable: (Char) -> Boolean) : LinkBuilder
    
  • ทีแรกเขียนแบบนี้
     val linkBuilder = arrayOf(DixLinkBuilder(dix)),
    

    แล้วเอา linkBuilder ไปใส่ให้ buildPath ก็เจ๊งเพราะมัน infer type ให้เป็น DixLinkBuilder array แต่เวลาใช้เจอ LinkBuilder array เวลาใช้งานก็ต้องไประบุ type ของ linkBuilder อยู่ดี

  • ชอบอันนี้
    return Link(s = context.leftBoundary,
                        linkType = LinkType.UNK,
                        wordCount = source.wordCount + 1,
                        unkCount = source.unkCount + 1)
    

    เวลาเจอ argument เยอะ ๆ มันจะพลาดได้นี่ใส่เป็น keyboard แทนได้ ต่อให้ check type มันก็พลาดง่าย ๆ อยู่ดี มี integer เพียบ

สรุปคือเรื่องจัดการ null ก็มึน ๆ นิดหน่อยแต่ก็แก้ได้ไม่ยากเท่าไหร่เพราะ IntelliJ IDEA มันเก่ง ถ้าใช้ Emacs เขียนท่าจะยาก; type inference มันใช้ได้ในกรณีง่าย ๆ กรณีไม่ง่ายก็ตามมาใส่เองอยู่ดี; ใส่ keyword ได้เจ๋งดี แต่ Python ก็มี; แต่รวม ๆ แล้วก็เขียนเสร็จไว ติดแต่ละประเด็นไม่นาน

ส่วะประสิทธิภาพออกมาประทับใจมาก จากเมื่อวานลอง wordcut-clj ซึ่งใช้ Clojure เยอะหน่อย ตัดคำบนไฟล์ 21 MB; จาก wordcut-clj ใช้เวลาประมาณ 1 นาที 8 วินาที ขนาดว่าใช้ prefixtree ที่ด้วย Kotlin แล้ว, ตัวใหม่ที่เขียนนี้ไวขึ้นเยอะตัดเสร็จใน 7.1 วินาที คือเร็วสูสี Rust เลย

Advertisements
Posted in ไม่มีหมวดหมู่

ใส่ความเห็น

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / เปลี่ยนแปลง )

Twitter picture

You are commenting using your Twitter account. Log Out / เปลี่ยนแปลง )

Facebook photo

You are commenting using your Facebook account. Log Out / เปลี่ยนแปลง )

Google+ photo

You are commenting using your Google+ account. Log Out / เปลี่ยนแปลง )

Connecting to %s