วงแหวนเว็บ

neizod's speculation

insufficient data for meaningful answer

โปรแกรมที่เขียนมันช้า...

Wednesday, October 17, 2012, 01:39 PM

เวลาเขียน Python แล้วต้อง implement อะไรประมาณนี้

numbers = [random() for r in range(1000)]

for i in range(100):
    print(max(numbers)**i)

จะระลึกตัวเสมอว่า implement ตรงๆ แบบนี้แล้วมันช้านะ

แต่ถ้า input ไม่ได้ใหญ่จนน่าเป็นห่วง ก็ไม่มีเหตุผลที่จะเขียนให้ยากขึ้น เพราะการแก้โดยเอา max(numbers) ไปไว้เป็นค่าคงที่นอก loop แม้จะทำให้โปรแกรมเร็วขึ้นก็ตาม แต่ก็จะเสีย readability ไปบางส่วน เวลากลับมาอ่านอาจจะสับสนใน logic ว่าส่วนนี้มีไว้ทำอะไรกันแน่ แถมถ้าภายหลังโปรแกรมถูกพัฒนาจนซับซ้อนมากๆ แล้ว ค่า max(numbers) อาจไม่เท่ากันทุกรอบที่วน loop ก็ได้ ทำให้เกิดเป็น bug ซ่อนเร้นอีก

แต่ถ้าต้องทำงานกับ loop ที่ใหญ่ขึ้น ซึ่งต้องการประสิทธิภาพที่ดีกว่าเดิมมากๆ การแก้ Python จนอ่านยากอาจไม่ใช่ความคิดที่เข้าท่าเท่าไหร่ ลองถอดโปรแกรมข้างต้นมาเขียนบน C++ ก็คงได้ประมาณนี้1

int main(void) {
    float numbers[100000];
    fill_with_random(numbers);

    for (int i=0; i<100; i++) {
        printf("%.32f\n", pow(max(numbers), i));
    }
    return 0;
}

ถึงตอนนี้จะเห็นว่า max(numbers) มีผลอย่างมากต่อประสิทธิภาพโปรแกรม การย้ายมันออกมาไว้นอก loop จะเป็นการกระทำที่มีเหตุผลขึ้นทันที

แต่ถ้าโปรแกรมเรามีอะไรแบบนี้เป็นสิบเป็นร้อยที่หละ การย้ายมือเองไม่สนุกแน่

ทางออกก็ง่ายๆ บอกให้ gcc มันทำแทนเราไปซะ

$ gcc -O2 exp-max.cpp

เพียงเท่านี้ก็จะได้ code ที่ยังคง logic + readability เดิมเอาไว้อยู่ พร้อมทั้งโปรแกรมที่เร็วกว่าเดิมเยอะ

แต่ถ้าโปรแกรมใหญ่มากๆ ก็ต้องรอ compile กันนานหน่อยนะ :P

กำลังคอมไพล์ – ภาพจาก xkcd

ป.ล. ว่าแต่ทำไมเด็กวิศวะคอมปี 4 ที่เขียน C++ มาตั้งแต่เข้ามหาลัย ถึงไม่รู้จัก optimization level กันวะ …

  1. ขนาดของ array / loop อาจเปลี่ยนไปยังค่าสูงกว่านี้ เพื่อให้เห็นได้ชัดว่าโปรแกรมทำงานช้าลงอย่างมีนัยสำคัญ 

neizod

author