Python CLI เร็วขึ้นแบบงงๆ ด้วย JIT Compiler จัดการไฟล์สบาย

สวัสดีครับ,

ผมมีเรื่องน่าตื่นเต้นมาเล่าให้ฟังครับ โปรแกรมเมอร์อย่างเราๆ ที่ชอบเขียน Python CLI สำหรับงานจัดการไฟล์เอย ประมวลผลข้อมูลเอย บางทีมันก็รอนานใช่ไหมครับ ผมก็เป็นนะ เลยไปเจอวิธีที่ช่วยให้มันเร็วขึ้นแบบงงๆ เลย คือใช้ JIT Compiler เข้ามาช่วย นี่แหละครับ Numba ตัวเด็ดของเรา วันนี้ผมจะมาลองทำให้ดูว่ามันช่วยได้จริงๆ นะครับ

ลองคิดดูว่าเรามีไฟล์ข้อมูลใหญ่ๆ แล้วต้องมานั่ง loop อ่านทีละบรรทัด ประมวลผล แล้วเขียนออกไปใหม่ แค่คิดก็เหนื่อยแล้วครับ ผมลองยกตัวอย่างง่ายๆ ให้ดูนะครับ สมมติเรามีไฟล์ data.txt ที่มีตัวเลขเยอะๆ แล้วเราอยากจะคูณเลขแต่ละบรรทัดด้วย 2 แล้ว Save เป็น output.txt แบบนี้นะครับ

โค้ดแบบบ้านๆ ก่อน JIT (อาจจะช้า):

# slow_processor.py
def process_file_slow(input_file, output_file):
    with open(input_file, 'r') as infile,
         open(output_file, 'w') as outfile:
        for line in infile:
            try:
                num = float(line.strip())
                result = num * 2
                outfile.write(f'{result}\
')
            except ValueError:
                # ถ้าไม่ใช่ตัวเลข ก็ข้ามไป
                continue

if __name__ == '__main__':
    # สร้างไฟล์สำหรับทดสอบ
    with open('data.txt', 'w') as f:
        for i in range(1_000_000):
            f.write(f'{i}\
')

    print('เริ่มประมวลผลแบบธรรมดา...')
    import time
    start_time = time.time()
    process_file_slow('data.txt', 'output_slow.txt')
    end_time = time.time()
    print(f'ใช้เวลาไป: {end_time - start_time:.2f} วินาที')

จากนั้น ลองรันดูนะครับ ถ้าไฟล์ใหญ่ๆ นะ รอไปเลยครับ ส่วนตัวผมก็รอนานอยู่ครับ

ทีนี้เรามาลองใช้ Numba JIT Compiler เข้ามาช่วยดีกว่าครับ ก่อนอื่นต้องติดตั้ง Numba ก่อนนะ:

pip install numba

แล้วเราก็แค่เพิ่ม @jit เข้าไปใน function ที่เราอยากให้มันเร็วขึ้นครับ ง่ายมากๆ เลยครับ แบบนี้เลย:

โค้ดแบบมี Numba JIT (เร็วขึ้นเยอะ):

# fast_processor.py
from numba import jit
import numpy as np # Numba ชอบทำงานกับ numpy มากๆ ครับ

@jit(nopython=True) # nopython=True คือทำให้เร็วที่สุด ไม่ต้องกลับไป Python interpreter
def process_numbers_jit(numbers):
    results = np.empty_like(numbers)
    for i in range(len(numbers)):
        results[i] = numbers[i] * 2
    return results

def process_file_fast(input_file, output_file):
    # อ่านข้อมูลทั้งหมดมาก่อน
    with open(input_file, 'r') as infile:
        # ใช้ list comprehension อ่านและกรองข้อมูล
        lines = [float(line.strip()) for line in infile if line.strip().replace('.', '', 1).isdigit()]

    numbers_array = np.array(lines, dtype=np.float64)

    # เอาไปเข้าฟังก์ชันที่ JIT แล้ว
    processed_numbers = process_numbers_jit(numbers_array)

    with open(output_file, 'w') as outfile:
        for num in processed_numbers:
            outfile.write(f'{num}\
')

if __name__ == '__main__':
    # สร้างไฟล์สำหรับทดสอบ (ใช้ไฟล์เดิม)
    with open('data.txt', 'w') as f:
        for i in range(1_000_000):
            f.write(f'{i}\
')

    print('เริ่มประมวลผลแบบ JIT...')
    import time
    start_time = time.time()
    process_file_fast('data.txt', 'output_fast.txt')
    end_time = time.time()
    print(f'ใช้เวลาไป: {end_time - start_time:.2f} วินาที')

เห็นไหมครับ แค่เพิ่ม @jit เข้าไป แล้วก็ปรับให้มันทำงานกับ numpy array หน่อย (Numba ชอบมากๆ) มันก็วิ่งฉิวเลยครับ จริงๆ แล้ว Numba มันจะแปลงโค้ด Python ที่เราเขียน ไปเป็นโค้ดเครื่อง (Machine Code) ทำให้มันรันได้เร็วขึ้นเหมือนเขียนด้วย C/C++ เลยครับ แต่เรายังเขียน Python เหมือนเดิม

ข้อควรรู้เล็กน้อยสำหรับ Numba: - มันจะเวิร์คดีกับโค้ดที่เน้นการคำนวณตัวเลข ลูปเยอะๆ ครับ - ถ้าโค้ดเราไปยุ่งกับ Python objects เยอะๆ หรือ I/O เยอะๆ มันอาจจะไม่ได้เห็นผลมากเท่าที่ควรนะครับ - @jit(nopython=True) จะเร็วที่สุด แต่ก็เขียนยากกว่านิดหน่อย เพราะต้องระวังเรื่อง Python object ที่ไม่รองรับ

สุดท้ายนี้ ผมหวังว่าเทคนิคนี้จะช่วยให้เพื่อนๆ โปรแกรมเมอร์ สามารถทำให้ Python CLI ของเราที่ต้องทำงานหนักๆ กับไฟล์ มีประสิทธิภาพที่ดียิ่งขึ้นนะครับ ใครมีคำถาม หรืออยากแชร์เทคนิคอื่นๆ ก็คอมเมนต์กันเข้ามาได้เลยนะครับ สวัสดีครับ!

อ้างอิง: - Numba Documentation: https://numba.pydata.org/ - NumPy Documentation: https://numpy.org/ "

Read more

ดราม่า "เบิร์ด วันว่างๆ" กับยาแนว: บทเรียนสำคัญของอินฟลูเอนเซอร์และความปลอดภัยบนโซเชียล

ดราม่า "เบิร์ด วันว่างๆ" กับยาแนว: บทเรียนสำคัญของอินฟลูเอนเซอร์และความปลอดภัยบนโซเชียล

เจาะลึกดราม่า "เบิร์ด วันว่างๆ" ใช้ยาแนวเล่นสงกรานต์ คำชี้แจง และผลกระทบต่อสังคม บทเรียนสำคัญสำหรับความรับผิดชอบของอินฟลูเอนเซอร์

By ทีมงาน devdog
Xiaomi 17T หลุดสเปคเด็ดบน Geekbench! ยืนยัน Dimensity 8500 พร้อมแบต 7,000mAh จ่อเปิดตัว

Xiaomi 17T หลุดสเปคเด็ดบน Geekbench! ยืนยัน Dimensity 8500 พร้อมแบต 7,000mAh จ่อเปิดตัว

Xiaomi 17T เตรียมเปิดตัว! พบข้อมูลบน Geekbench ยืนยันใช้ชิป Dimensity 8500 พร้อมแบตเตอรี่จุใจ 7,000mAh คาดบุกตลาดรองเรือธงเร็วๆ นี้

By ทีมงาน devdog
กยศ. เปิดทางรอด! ปรับโครงสร้างหนี้ออนไลน์ หยุดถูกฟ้อง ก่อน 5 ก.ค. 69

กยศ. เปิดทางรอด! ปรับโครงสร้างหนี้ออนไลน์ หยุดถูกฟ้อง ก่อน 5 ก.ค. 69

ผู้กู้ กยศ. กว่า 1 แสนราย เสี่ยงถูกฟ้อง! รีบปรับโครงสร้างหนี้ออนไลน์ผ่านเป๋าตัง/ThaID ก่อน 5 ก.ค. 69 รับสิทธิประโยชน์ ลดดอกเบี้ย หลีกเลี่ยงคดีความ

By ทีมงาน devdog
Baseus MC2: หูฟังคลิปหนีบหูสุดล้ำ แบตอึด 60 ชม. เสียง LDAC กันน้ำ IP67 เพื่ออิสระทางเสียงของคุณ

Baseus MC2: หูฟังคลิปหนีบหูสุดล้ำ แบตอึด 60 ชม. เสียง LDAC กันน้ำ IP67 เพื่ออิสระทางเสียงของคุณ

พบ Baseus MC2 หูฟังคลิปหนีบหูดีไซน์ล้ำ สวมใส่สบายตลอดวัน ด้วยแบตเตอรี่ 60 ชม., กันน้ำ IP67, เสียง LDAC ระดับ Hi-Res และราคาเข้าถึงง่าย

By ทีมงาน devdog