เวลาพูดว่า "ถ้า ก แล้ว ข" เนี่ย มันเป็นการพูดแบบสนใจตอนที่เงื่อนไข ก เป็นจริงอย่างเดียว ถ้าเงื่อนไข ก ไม่เกิด เหตุการณ์ ข ที่ตามมาจะเกิดหรือไม่เกิดก็ได้
ตัวอย่างเช่น "ถ้าฝนตก ผ้าที่ตากไว้จะเปียก" จะเห็นได้ว่า ฝนตกแล้วยังไงผ้าต้องเปียกแน่ๆ ไม่มีทางที่ฝนตกแต่ผ้าไม่เปียกได้เลย แต่เราจะไม่สามารถระบุได้เลยว่าหากฝนไม่ตกแล้วผ้าจะเปียกหรือไม่ (มันไม่เกี่ยวโยงกันเลย)
สิ่งที่น่าประหลาดใจมาก คือหลายครั้งเรามักจะคิดว่ามันเชื่อมโยงกันได้ คือคิดว่า "ถ้าไม่ ก แล้วไม่ ข" ตามไปด้วย อย่างเช่นจากด้านบนนี้ เราอาจคิดว่า "ถ้าฝนไม่ตก ผ้าที่ตากไว้จะไม่เปียก" ซึ่งจะเห็นได้ว่าผิดถนัด เพราะเงื่อนไขของการที่ผ้าเปียกอาจไม่ได้เกิดจากฝนตกอย่างเดียว ตอนรดน้ำต้นไม้อาจสะบัดสายน้ำไปโดนผ้าก็เป็นได้
ดังนั้นถ้าจะหัวหมอหน่อย เวลามีคนบอกว่า "ถ้าฝนตก แล้วเก็บผ้า" เนี่ย เราสามารถไปเก็บผ้าได้ทันทีเลย ไม่ต้องรอให้ฝนตกนะ (เพราะสาเหตุมันไม่เกี่ยวโยงกัน ดังนั้นเมื่อฝนไม่ตก จะเก็บผ้าหรือไม่เก็บผ้าก็ได้)
ทางแก้คือเปลี่ยนไปใช้รูปประโยค "ก ก็ต่อเมื่อ ข" แทน ซึ่งหมายความคือ "ถ้า ก แล้ว ข" และ "ถ้า ข แล้ว ก" ทั้งสองอย่าง
นั่นก็คือเปลี่ยนประโยคนั้นเป็น "ฝนตกก็ต่อเมื่อเก็บผ้า" หรือเพื่อให้อ่านได้เข้าใจง่ายขึ้น "เก็บผ้าก็ต่อเมื่อฝนตก" แบบนี้แล้ว การจะเก็บผ้าต้องทำตอนที่ฝนตกเท่านั้น ถ้าฝนไม่ตกห้ามเก็บผ้าเด็ดขาดครับ
Oct 23, 2012
Oct 17, 2012
โปรแกรมที่เขียนมันช้า...
เวลาเขียน Python แล้วต้อง implement อะไรประมาณนี้
ส่วนถ้าต้องการประสิทธิภาพที่ดีกว่าเดิมมากๆ การแก้ Python จนอ่านยากอาจไม่ใช่ความคิดที่เข้าท่าเท่าไหร่ ลองถอดโปรแกรมเดิมมาเขียนบน C++ แบบเป๊ะๆ ก็คงได้ประมาณนี้
(ตัวเลขขนาด array / loop ควรเปลี่ยนไปยังค่าสูงกว่านี้ เพื่อให้เห็นได้ชัดว่าโปรแกรมทำงานได้ช้าลง)
ถึงตอนนี้จะเห็นว่า
แต่ถ้าโปรแกรมเรามีอะไรแบบนี้เป็นสิบเป็นร้อยที่หละ การย้ายมือเองไม่สนุกแน่
ทางออกก็ง่ายๆ บอกให้ gcc มันทำแทนเราไปซะ
แต่ถ้าโปรแกรมใหญ่มากๆ ก็ต้องรอ compile กันนานหน่อยนะ :P
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 ซ่อนเร้นอีกส่วนถ้าต้องการประสิทธิภาพที่ดีกว่าเดิมมากๆ การแก้ Python จนอ่านยากอาจไม่ใช่ความคิดที่เข้าท่าเท่าไหร่ ลองถอดโปรแกรมเดิมมาเขียนบน C++ แบบเป๊ะๆ ก็คงได้ประมาณนี้
int main(void) { float numbers[1000]; 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
Oct 7, 2012
Nessun Dorma
คือปรกติเพลงประกอบโฆษณาที่เป็นเพลงคลาสสิก เคยเจอแต่พวกเพลงบรรเลงแฮะ ไม่ค่อยเจอ aria อะไรอย่างนี้ซักเท่าไหร่ จดเก็บไว้หน่อยๆ :3
Subscribe to:
Posts (Atom)