0Pricing
C Academy · บทเรียน

การปรับขนาดและปัจจัยโหลด

ปรับแต่งประสิทธิภาพ

การปรับขนาดและปัจจัยโหลด เป็นบทเรียน 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 ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. ฟังก์ชันแฮช
  2. การจัดการการชนกัน
  3. แทรก ค้นหา และลบ
  4. การปรับขนาดและปัจจัยโหลด
← กลับไปที่ C Academy