ลอง 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
This เรื่อง was posted in ไม่มีหมวดหมู่. Bookmark the permalink.

ใส่ความเห็น

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