ข้ามไปเนื้อหาหลัก

เจอปัญหา 140 จุดในฟังก์ชันเดียวหลังพอร์ตโค้ด Python สู่ Rust

นักพัฒนาแชร์ประสบการณ์พอร์ตไลบรารีวัดความคล้ายคลึงของข้อความจาก Python สู่ Rust และพบความท้าทายเรื่องความต่างของผลลัพธ์ถึง 140 จุด

เรียบเรียงโดย AI
Inewgen
10 Aug 2026ที่มา: Dev.to3 นาทีอ่าน (0 ครั้ง)
แชร์
เจอปัญหา 140 จุดในฟังก์ชันเดียวหลังพอร์ตโค้ด Python สู่ Rust

ภาพประกอบจากคลังภาพสต็อก ไม่ใช่ภาพจากเหตุการณ์จริง

ขนาดตัวอักษร
  • การพอร์ตโค้ดไม่ใช่แค่ทำให้คอมไพล์ผ่าน แต่ต้องพิสูจน์ว่าโค้ดใหม่ทำงานได้ผลลัพธ์ตรงกันทุกประการ
  • การใช้ Subprocess CLI สื่อสารผ่าน JSON ทำให้เกิดข้อจำกัดในการส่งฟังก์ชันแบบ Lambda ไปยัง Rust
  • การทำ Differential Fuzzing ช่วยตรวจพบความแตกต่างถึง 140 จุดที่ชุดทดสอบปกติมองไม่เห็น
  • ข้อผิดพลาดใน Jaro-Winkler มาจากการละเลยเกณฑ์มาตรฐานความต่าง 0.7 ตามบทความวิชาการอายุ 35 ปี

การพอร์ตไลบรารีจากภาษาหนึ่งไปอีกภาษาหนึ่งไม่ใช่แค่เรื่องของการแปลโค้ดให้ออกมาคอมไพล์ผ่าน แต่ปัญหาทางวิศวกรรมที่ยากกว่าคือการพิสูจน์ว่าโค้ดชุดใหม่ให้ความหมายเดิมเหมือนกับโค้ดต้นฉบับผ่านอัลกอริทึมมากกว่า 30 รูปแบบ กรณีศึกษาครั้งนี้เกิดขึ้นจากการพอร์ตไลบรารีวัดความคล้ายคลึงของสตริงจาก Python ไปเป็นภาษา Rust ในชื่อโปรเจกต์ textdistance-rs

ไลบรารีดั้งเดิมครอบคลุมอัลกอริทึมจำนวนมาก ได้แก่ Edit-based distances (เช่น Levenshtein, Hamming), Token-based measures (เช่น Jaccard, Cosine), Sequence-based methods, Phonetic algorithms และ Compression-based distances รวมกว่า 30 อัลกอริทึมที่ต้องเขียนใหม่ด้วยภาษา Rust ทั้งหมด ก่อนจะเริ่มเขียนโค้ด การตัดสินใจครั้งแรกคือการเชื่อมชุดทดสอบ Python เดิมที่มีอยู่ 397 ชุดเข้ากับโค้ด Rust อย่างไร

  • เลือกใช้ Subprocess CLI เป็น Binary อิสระสื่อสารผ่าน JSON
  • ใช้ Python Adapter เรียกใช้งานผ่าน Standard Input/Output
  • เลือกวิธีนี้เพื่อความรวดเร็ว แต่ปิดกั้นทางเลือกอื่นในอนาคต
software debugging code terminal display

ภาพประกอบจากคลังภาพสต็อก ไม่ใช่ภาพจากเหตุการณ์จริง

การตัดสินใจใช้ Subprocess และ JSON แลกมาด้วยความเร็วในการพัฒนาและการแยกกระบวนการทำงานที่สะอาด แต่ก็สร้างข้อจำกัดทางสถาปัตยกรรมอย่างหลีกเลี่ยงไม่ได้ โดยเฉพาะการส่งฟังก์ชันจำพวก Callback หรือ Lambda ที่ไม่สามารถแปลงเป็น JSON ได้ ส่งผลให้ชุดทดสอบบางส่วนไม่สามารถทำงานข้ามระบบได้ตามที่ออกแบบไว้แต่แรก

ช่วงเวลาที่ดีบั๊กยากที่สุดเกิดขึ้นกับอัลกอริทึม Jaro-Winkler ซึ่งอ้างอิงจากบทความวิชาการของ William Winkler ในปี 1990 โดยมีการเพิ่มโบนัสสำหรับสตริงที่มีคำนำหน้าเหมือนกัน แต่เวอร์ชันแรกที่เขียนขึ้นกลับนำโบนัสไปบวกแบบไม่มีเงื่อนไข ซึ่งขัดกับหลักการที่ระบุว่าระบบจะเพิ่มโบนัสต่อเมื่อคะแนน Jaro พื้นฐานเกินเกณฑ์ 0.7 เท่านั้น ไม่เช่นนั้นคะแนนของสตริงที่ไม่เกี่ยวข้องกันจะถูกดันให้สูงขึ้นเกินจริง

ไม่อยากพลาดข่าวใหม่?

สมัครรับสรุปข่าวสารใหม่ทางอีเมล ไม่บ่อยจนรำคาญ

โฆษณา

"When you port a library, you inherit its citations, not just its code."

ผู้พัฒนาโปรเจกต์ textdistance-rs

คำถามคือเหตุใดจึงพบความแตกต่างมากถึง 140 จุด ทั้งที่ชุดทดสอบยูนิตเทสต์ของ Jaro-Winkler ผ่านทั้งหมด คำตอบคือการใช้เทคนิค Differential Fuzzing ด้วยการรันอินพุตแบบสุ่มทั้งสองระบบแล้วนำผลลัพธ์มาเทียบกัน โดยใช้ไลบรารี Hypothesis สร้างชุดข้อมูลอินพุตอันหลากหลาย ซึ่งช่วยบีบอัดข้อผิดพลาดให้เหลือเคสขนาดเล็กที่นำมาวิเคราะห์บนกระดาษได้ง่าย จนกระทั่งลดความแตกต่างลงเหลือศูนย์ในส่วนที่ผ่านท่อสื่อสารได้

140จุดความต่างที่ตรวจพบ
397ชุดทดสอบดั้งเดิมใน Python

อย่างไรก็ตาม ยังมีอัลกอริทึมประเภท Alignment เช่น Needleman-Wunsch และ Smith-Waterman ที่รับพารามิเตอร์ sim_func เป็น Python Callable สำหรับให้คะแนนความคล้ายคลึงของตัวอักษร ซึ่งฟังก์ชันประเภท Lambda เหล่านี้ไม่สามารถแปลงเป็น JSON เพื่อส่งไปยังกระบวนการทำงานของ Rust ได้ ส่งผลให้ชุดทดสอบจำนวน 22 ชุดไม่สามารถรันได้เนื่องจากข้อจำกัดทางสถาปัตยกรรมตั้งแต่วันแรก

ที่มา: Dev.to

ความคิดเห็น

แสดงความคิดเห็น
0/2000

พบข้อมูลผิดพลาดในบทความนี้? แจ้งปัญหาบทความนี้