วันนี้เรามาคุยกันเรื่องการเขียน loop ให้มีประสิทธิภาพกันดีกว่า ไม่ว่าใช้ภาษาไหนอยู่ การเขียน loop ที่ดีก็เป็นทักษะสำคัญที่จะช่วยให้โค้ดของเราทำงานได้เร็วขึ้นและมีประสิทธิภาพมากขึ้น ซึ่งในบทความนี้จะยกตัวอย่างบางเทคนิคหรือสิ่งที่ควรระวังในการใช้งาน loop มาให้ลองดูกันครับ
หลักการสำคัญในการเขียน Loop
- กำหนดเป้าหมายให้ชัดเจน: ก่อนเขียน loop ต้องรู้ว่าเราต้องการทำอะไร
- เลือกประเภท loop ให้เหมาะสม: แต่ละภาษามี loop หลายแบบ เลือกใช้ให้เหมาะกับงาน
- ควบคุมการทำงาน: ต้องมีเงื่อนไขที่ชัดเจนในการหยุด loop
- ใช้ทรัพยากรอย่างมีประสิทธิภาพ: หลีกเลี่ยงการทำงานซ้ำโดยไม่จำเป็น
เทคนิคและสิ่งที่ควรหลีกเลี่ยง
1. หลีกเลี่ยงการคำนวณซ้ำ
การคำนวณซ้ำในลูปทำให้โปรแกรมทำงานช้าลง โดยเฉพาะเมื่อการคำนวณนั้นต้องใช้เวลาและทรัพยากรในการประมวลผล เช่น การหาค่าเฉลี่ยในตัวอย่างนี้
ตัวอย่างโค้ด
const numbers = [1, 2, 3, 4, 5];
function getAverage(numbers) {
const length = numbers.length;
return numbers.reduce((sum, num) => sum + num, 0) / length;
}
// แบบไม่ดี
for (let i = 0; i < numbers.length; i++) {
const average = getAverage(numbers); // คำนวณค่าเฉลี่ยซ้ำในทุก ๆ รอบ
console.log(numbers[i], average);
// โค้ดการทำงานอื่น ๆ
}
// แบบดี
const average = getAverage(numbers); // คำนวณค่าเฉลี่ยเพียงครั้งเดียว
for (let i = 0; i < numbers.length; i++) {
console.log(numbers[i], average);
// โค้ดการทำงานอื่น ๆ
}
JavaScriptอธิบายโค้ดเแต่ละแบบ
- ในโค้ดแบบไม่ดี เราเรียกใช้ฟังก์ชัน getAverage(numbers) ภายในลูป ซึ่งหมายความว่าโปรแกรมจะคำนวณค่าเฉลี่ยซ้ำ ๆ ในทุก ๆ รอบของลูป ทำให้เกิดการใช้ทรัพยากรและเวลาในการประมวลผลมากเกินไป โดยที่ผลลัพธ์ที่ได้จากการคำนวณนั้นไม่เปลี่ยนแปลงในแต่ละรอบ
- ในโค้ดแบบดี เราคำนวณค่าเฉลี่ยเพียงครั้งเดียวก่อนที่จะเริ่มลูป และเก็บผลลัพธ์ไว้ในตัวแปร average จากนั้นจึงใช้ค่าเฉลี่ยนี้ภายในลูป ซึ่งช่วยลดจำนวนการคำนวณและทำให้โปรแกรมทำงานได้เร็วขึ้นและมีประสิทธิภาพมากขึ้น
2. ใช้ break เมื่อเจอสิ่งที่ต้องการ
การใช้คำสั่ง break ในลูปช่วยให้เราสามารถหยุดการทำงานของลูปได้ทันทีเมื่อพบเงื่อนไขที่ต้องการ ซึ่งช่วยเพิ่มประสิทธิภาพและลดเวลาในการประมวลผล โดยเฉพาะในกรณีที่เราต้องการค้นหาค่าหรือเงื่อนไขเฉพาะในข้อมูล
ตัวอย่างโค้ด
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const target = 7; // ค่าที่เราต้องการค้นหา
for (let i = 0; i < numbers.length; i++) {
if (numbers[i] === target) {
console.log(`พบค่าที่ต้องการ: ${numbers[i]}`);
break; // ออกจากลูปเมื่อพบค่าที่ต้องการ
}
}
JavaScript
ในโค้ดนี้
- เราสร้างอาเรย์ numbers ที่มีค่าตั้งแต่ 1 ถึง 10
- เรากำหนดให้ target เป็น 7 ซึ่งเป็นค่าที่เราต้องการค้นหา
- ลูป for จะทำการวนรอบอาเรย์ numbers โดยใช้ตัวแปร i เป็นตัวนับ
- ในแต่ละรอบของลูป เราจะตรวจสอบว่า numbers[i] ตรงกับ target มั้ย
- ถ้าพบค่าที่ต้องการ จะแสดงข้อความ “พบค่าที่ต้องการ: 7” และใช้คำสั่ง break เพื่อออกจากลูป
3. ใช้ continue เพื่อข้ามการทำงานที่ไม่จำเป็น
คำสั่ง continue ใน JavaScript ใช้เพื่อข้ามการทำงานในรอบปัจจุบันของลูปและไปยังรอบถัดไป โดยเฉพาะเมื่อพบเงื่อนไขที่ไม่ต้องการทำงานต่อ ซึ่งช่วยให้โค้ดมีความชัดเจนและมีประสิทธิภาพมากขึ้น
ตัวอย่างโค้ด
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
for (let i = 0; i < numbers.length; i++) {
if (numbers[i] % 2 === 0) {
continue; // ข้ามการทำงานเมื่อพบเลขคู่
}
console.log(`เลขคี่: ${numbers[i]}`); // จะแสดงผลเฉพาะเลขคี่
}
JavaScript- การตรวจสอบเงื่อนไข ในตัวอย่างนี้ เรามี Array ของตัวเลขและต้องการแสดงเฉพาะเลขคี่ การใช้ลูป for จะช่วยให้เราสามารถตรวจสอบสมาชิกแต่ละตัวใน Array ได้
- การใช้ continue เมื่อพบเลขคู่ (numbers[i] % 2 === 0), เราจะใช้คำสั่ง continue เพื่อข้ามการทำงานในรอบนั้น และไปยังรอบถัดไปทันที นั่นหมายความว่าเราจะไม่แสดงผลสำหรับเลขคู่
4. ระวัง Infinite Loop
Infinite Loop คือ ลูปที่ไม่มีเงื่อนไขในการหยุดทำงาน ซึ่งหมายความว่าลูปจะทำงานต่อไปเรื่อย ๆ โดยไม่มีวันสิ้นสุด ส่งผลให้โปรแกรมไม่สามารถทำงานอื่น ๆ ต่อไปได้
ตัวอย่างของ Infinite Loop
// ตัวอย่าง Infinite Loop
let i = 0;
while (i < 5) {
console.log(i);
// ไม่มีการปรับปรุงค่า i ทำให้เงื่อนไขยังคงเป็นจริง
}
JavaScriptในตัวอย่างนี้ ลูป while จะทำงานตลอดไปเพราะค่า i ไม่ได้ถูกเปลี่ยนแปลง ทำให้เงื่อนไข i < 5 เป็นจริงเสมอ
วิธีป้องกัน Infinite Loop
- ตรวจสอบเงื่อนไขของลูป: ให้แน่ใจว่าเงื่อนไขในการหยุดลูปมีความเหมาะสมและสามารถเป็นจริงได้
- อัปเดตตัวแปรที่ต้องใช้: ควรมีการเปลี่ยนแปลงค่าของตัวแปรที่ใช้ในเงื่อนไขของลูปเพื่อให้สามารถออกจากลูปได้
- ใช้คำสั่ง break อย่างระมัดระวัง: ใช้คำสั่ง break เพื่อออกจากลูปเมื่อเงื่อนไขบางอย่างเกิดขึ้น
5. เลี่ยงการแก้ไขขนาดของ Array ระหว่าง Loop
การแก้ไขขนาดของ Array (เช่น การเพิ่มหรือลบสมาชิก) ตอนที่ทำงานในลูปสามารถทำให้เกิดปัญหาได้ เนื่องจากการเปลี่ยนแปลงขนาดของ Array จะส่งผลต่อค่า length และตำแหน่งของสมาชิกใน Array ซึ่งอาจทำให้ลูปทำงานผิดพลาดหรือข้ามสมาชิกบางตัวไป
ตัวอย่างโค้ด
// อันตราย! อาจทำให้ loop ทำงานผิดพลาด
const myArray = [1, 2, 3, 4, 5];
for (let i = 0; i < myArray.length; i++) {
if (myArray[i] % 2 === 0) { // ตรวจสอบว่าเป็นเลขคู่
myArray.splice(i, 1); // ลบสมาชิกที่เป็นเลขคู่
}
}
JavaScriptปัญหาที่อาจเกิดขึ้น
- การข้ามสมาชิก: เมื่อใช้ splice เพื่อลบสมาชิกใน Array ขนาดของ Array จะลดลง แต่ค่าของ i จะเพิ่มขึ้นตามรอบของลูป ทำให้บางสมาชิกถูกข้ามไป ตัวอย่างเช่น ถ้า myArray มีค่า [1, 2, 3, 4, 5] และเมื่อ i = 1 (ซึ่งเป็นเลขคู่ 2) สมาชิกนี้จะถูกลบออก ทำให้ myArray กลายเป็น [1, 3, 4, 5] และในรอบถัดไป i จะเป็น 2 ซึ่งหมายถึงการตรวจสอบเลข 4 แทนที่จะเป็นเลข 3
- ผลลัพธ์ที่ไม่คาดคิด: ผลลัพธ์สุดท้ายอาจไม่ตรงกับความคาดหวัง เช่น ค่าที่ควรจะถูกลบอาจยังคงอยู่ใน Array
6. Optimize โค้ดอยู่เสมอ
ถึงการใช้ลูปจะเป็นพื้นฐานในการเขียนโค้ด แต่เราก็ไม่ควรลืมที่จะปรับปรุงโค้ดของเราอยู่เสมอ ซึ่งรวมถึงการใช้งานลูปด้วย เช่น
- ใช้โครงสร้างข้อมูลที่เหมาะสม: เลือกใช้หรือเปลี่ยนโครงสร้างข้อมูลให้เหมาะกับงาน เช่น ใช้ Set แทน Array เมื่อต้องการเก็บค่าที่ไม่ซ้ำกัน
- ใช้ฟังก์ชันของภาษา: ใช้ฟังก์ชันที่มีอยู่แล้วในภาษา เช่น map, filter, reduce ใน JavaScript
- เลือกโครงสร้างข้อมูลอย่างเหมาะสม: โดยเลือกตามงานที่ต้องนำไปใช้ ในบางสถานการณ์อาจจะเลือกใช้ Object, Record หรือ Map ในการเก็บข้อมูลดีกว่าสร้างเป็น Array
สรุป
การเขียน Loop ที่ดีไม่ได้แค่ทำให้โค้ดทำงานได้ แต่ยังช่วยให้โปรแกรมของเราเร็วขึ้น ประหยัดทรัพยากรมากขึ้น และที่สำคัญคือ อ่านง่ายขึ้นด้วย ในบทความนี้ยกตัวอย่างด้วย JavaScript แต่ว่าหลักการต่าง ๆ น่าจะพอเอาไปปรับใช้กับภาษาอื่น ๆ ได้ด้วย หวังว่าจะสนุกกับการเขียนโค้ดมากขึ้นนะครับ