การปรับขนาดและปัจจัยโหลด
ปรับแต่งประสิทธิภาพ
การปรับขนาดและปัจจัยโหลด เป็นบทเรียน C Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน C Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส C Academy มีบทเรียนทั้งหมด 4 บทเรียน
อัตราการใช้งานคืออะไร
อัตราการใช้งานคืออัตราส่วนระหว่างจำนวนรายการที่จัดเก็บกับจำนวนช่อง: alpha = size / capacity ค่านี้บอกว่าตารางเต็มเพียงใดและส่งผลโดยตรงต่อประสิทธิภาพ
เหตุใดอัตราการใช้งานจึงสำคัญ
เมื่ออัตราการใช้งานสูงขึ้น ช่องจะมีสายโซ่ที่ยาวขึ้น (หรือการตรวจสอบจะเกิดการกระจุกตัว) ทำให้การดำเนินการช้าลง
- อัลฟาต่ำ: เร็วแต่สิ้นเปลืองหน่วยความจำ
- อัลฟาสูง: ประหยัดพื้นที่แต่ช้า
ค่าเป้าหมายทั่วไปสำหรับการเชื่อมโยงคือ 0.75
การคำนวณอัตราการใช้งาน
คำนวณเป็นอัตราส่วนแบบจำนวนจริง เพื่อให้เปรียบเทียบกับค่าขีดจำกัดได้
#include <stdio.h>
int main(void) {
unsigned size = 12, capacity = 16;
double alpha = (double)size / capacity;
printf("load factor = %.2f\n", alpha);
return 0;
}ควรปรับขนาดเมื่อใด
หลังการแทรกแต่ละครั้ง ให้ตรวจสอบว่าอัตราการใช้งานเกินค่าขีดจำกัดหรือไม่ หากเกิน ให้ขยายตาราง (โดยปกติจะเพิ่มความจุเป็นสองเท่า) และแฮชใหม่
#include <stdio.h>
int should_grow(unsigned size, unsigned cap) {
return (double)size / cap > 0.75;
}
int main(void) {
printf("%d\n", should_grow(13, 16)); /* 0.8125 -> 1 */
printf("%d\n", should_grow(10, 16)); /* 0.625 -> 0 */
return 0;
}คำอธิบายการแฮชใหม่
คุณไม่สามารถคัดลอกช่องไปตรง ๆ ได้ เพราะดัชนีของแต่ละคีย์ขึ้นอยู่กับความจุ การแฮชใหม่จะคำนวณช่องของทุกคีย์ใหม่โดยอิงความจุใหม่ แล้วแทรกคีย์เหล่านั้นอีกครั้ง
ฟังก์ชันปรับขนาด
จัดสรรอาร์เรย์ช่องใหม่ที่มีขนาดใหญ่ขึ้น เดินผ่านโหนดเก่าทุกโหนดและย้ายไปยังอาร์เรย์ใหม่โดยใช้ความจุใหม่ จากนั้นสลับอาร์เรย์ ในที่นี้คือการคำนวณดัชนีใหม่ส่วนสำคัญ
#include <stdio.h>
unsigned long djb2(const char *s){unsigned long h=5381;int c;while((c=(unsigned char)*s++))h=((h<<5)+h)+c;return h;}
int main(void) {
const char *key = "session";
unsigned old_cap = 8, new_cap = 16;
printf("old slot = %lu\n", djb2(key) % old_cap);
printf("new slot = %lu\n", djb2(key) % new_cap);
return 0;
}การย้ายโหนดโดยไม่จัดสรรใหม่
เมื่อใช้การเชื่อมโยง คุณสามารถย้ายโหนดเดิมไปยังอาร์เรย์ใหม่แทนการจัดสรรโหนดใหม่ได้ ถอดโหนดแต่ละตัวออก คำนวณช่องใหม่ แล้วนำไปไว้ด้านหน้า
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct Node { char *key; struct Node *next; } Node;
unsigned long djb2(const char *s){unsigned long h=5381;int c;while((c=(unsigned char)*s++))h=((h<<5)+h)+c;return h;}
int main(void) {
Node *old[2] = {0};
Node *a = malloc(sizeof *a); a->key = strdup("x"); a->next = NULL; old[0] = a;
Node *new_b[4] = {0};
/* move node a */
unsigned i = djb2(a->key) % 4;
a->next = new_b[i]; new_b[i] = a;
printf("moved to slot %u\n", i);
return 0;
}กลยุทธ์การขยาย
การเพิ่มความจุเป็นสองเท่าช่วยให้ต้นทุนการแทรกแบบเฉลี่ยตลอดการใช้งานเป็น O(1): แม้การปรับขนาดจะใช้เวลา O(n) แต่เกิดขึ้นไม่บ่อยพอที่ต้นทุนเฉลี่ยต่อการแทรกจะคงที่
ค่าความจุที่เป็นกำลังของสองยังทำให้ใช้มาสก์ AND ที่รวดเร็วได้
#include <stdio.h>
int main(void) {
unsigned cap = 8;
for (int i = 0; i < 4; i++) {
printf("capacity = %u\n", cap);
cap *= 2;
}
return 0;
}การลดขนาด
คุณอาจลดขนาดเมื่ออัตราการใช้งานลดลงต่ำเกินไป (เช่น ต่ำกว่า 0.1) หลังจากลบหลายครั้ง การลดขนาดช่วยเรียกคืนหน่วยความจำ แต่เพิ่มต้นทุนการแฮชใหม่ ดังนั้นควรทำอย่างระมัดระวังเพื่อหลีกเลี่ยงการปรับขนาดไปมา
การระบุตำแหน่งแบบเปิดกับอัตราการใช้งาน
ตารางแบบระบุตำแหน่งแบบเปิดไวต่ออัตราการใช้งานมากกว่ามาก ประสิทธิภาพจะลดลงอย่างรุนแรงเมื่ออัลฟาเข้าใกล้ 1 ดังนั้นโดยทั่วไปจึงปรับขนาดที่ค่า0.5 ถึง 0.7 ซึ่งต่ำกว่า 0.75 ของการเชื่อมโยง
การสาธิตต้นทุนแบบเฉลี่ยตลอดการใช้งาน
จำลองการแทรกที่เพิ่มความจุเป็นสองเท่าเมื่อถึง 0.75 และนับงานทั้งหมด เพื่อแสดงให้เห็นว่าค่าเฉลี่ยยังคงต่ำ
#include <stdio.h>
int main(void) {
unsigned cap = 4, size = 0;
long work = 0;
for (int i = 0; i < 100; i++) {
size++; work++; /* the insert */
if ((double)size / cap > 0.75) { work += size; cap *= 2; } /* rehash */
}
printf("inserts=%u total_work=%ld avg=%.2f\n", size, work, (double)work/size);
return 0;
}ตรวจสอบความเข้าใจ
ทดสอบความเข้าใจของคุณเกี่ยวกับการปรับขนาด
สรุปทบทวน
คุณได้เรียนรู้การปรับประสิทธิภาพของตารางแฮช
- อัตราการใช้งาน = ขนาด / ความจุ
- ปรับขนาดเมื่อค่าเกินขีดจำกัด (ประมาณ 0.75 สำหรับการเชื่อมโยง)
- ต้องแฮชใหม่เพราะดัชนีขึ้นอยู่กับความจุ
- การเพิ่มความจุเป็นสองเท่าให้การแทรกแบบเฉลี่ยตลอดการใช้งานเป็น O(1)
คำถามที่พบบ่อย
บทเรียน “การปรับขนาดและปัจจัยโหลด” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “การปรับขนาดและปัจจัยโหลด” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส C Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส C Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “การปรับขนาดและปัจจัยโหลด”
ปรับแต่งประสิทธิภาพ คุณปฏิบัติ C Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน C Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน C Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน
บทเรียน “การปรับขนาดและปัจจัยโหลด” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน C Academy นี้ได้ไหม
ได้ บทเรียน C Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- ฟังก์ชันแฮช
- การจัดการการชนกัน
- แทรก ค้นหา และลบ
- การปรับขนาดและปัจจัยโหลด