ด้วยมือ
หากหน่วยความจำไม่ใช่ทรัพยากรที่กระจัดกระจายมากฉันพิจารณาการทำงานในกลุ่มที่ใหญ่กว่า
นี่คือบางส่วนของรหัสเทียม
class Chunk {
Chunk new(int size) {...}
void setPixel(int x, int y, int value) {...}
int getPixel(int x, int y) {...}
}
class Grid {
Map<int, Map<Chunk>> chunks;
Grid new(int chunkSize) {...}
void setPixel(int x, int y, int value) {
getChunk(x,y).setPixel(x % chunkSize, y % chunkSize, value);//actually the modulo could be right in Chunk::setPixel and getPixel for more safety
}
int getPixel(int x, int y) { /*along the lines of setPixel*/ }
private Chunk getChunk(int x, int y) {
x /= chunkSize;
y /= chunkSize;
Map<Chunk> row = chunks.get(y);
if (row == null) chunks.set(y, row = new Map<Chunk>());
Chunk ret = row.get(x);
if (ret == null) row.set(x, ret = new Chunk(chunkSize));
return ret;
}
}
การดำเนินการนี้ค่อนข้างไร้เดียงสา
สำหรับหนึ่งมันสร้างชิ้นใน getPixel (โดยทั่วไปมันจะดีกว่าเพียงแค่กลับ 0 หรือดังนั้นถ้าไม่มีชิ้นกำหนดไว้สำหรับตำแหน่งนั้น) ประการที่สองมันขึ้นอยู่กับสมมติฐานที่ว่าคุณมีการใช้งานแผนที่ที่รวดเร็วและปรับขนาดได้อย่างเพียงพอ เพื่อความรู้ของฉันทุกภาษาที่ดีมีหนึ่ง
นอกจากนี้คุณจะต้องเล่นกับขนาดก้อน สำหรับบิตแมปที่หนาแน่นขนาดก้อนใหญ่นั้นดีสำหรับบิตแมปที่เบาบางขนาดอันเล็กจะดีกว่า ในความเป็นจริงสำหรับคนที่กระจัดกระจายมาก "ขนาดก้อน" ของ 1 เป็นดีที่สุดการแสดง "ชิ้น" ตัวเองล้าสมัยและลดโครงสร้างข้อมูลไปยังแผนที่ int ของแผนที่ int ของพิกเซล
ออกจากชั้นวาง
วิธีแก้ไขปัญหาอื่นอาจดูไลบรารีกราฟิกบางรายการ พวกเขาค่อนข้างดีในการวาดบัฟเฟอร์สองมิติหนึ่งไปยังอีกที่หนึ่ง นั่นหมายความว่าคุณเพียงแค่จัดสรรบัฟเฟอร์ที่มีขนาดใหญ่ขึ้นและดึงต้นฉบับมาที่พิกัดตาม
ตามกลยุทธ์ทั่วไป: เมื่อมี "บล็อกหน่วยความจำที่กำลังเติบโตแบบไดนามิก" เป็นความคิดที่ดีที่จะจัดสรรหลาย ๆ บล็อกเมื่อมีการใช้งานหมด นี่เป็นหน่วยความจำที่ค่อนข้างแรง แต่ลดการจัดสรรและคัดลอกค่าใช้จ่าย การนำเวกเตอร์ไปใช้ส่วนใหญ่จะจัดสรรสองเท่าของขนาดเมื่อเกินขนาด ดังนั้นโดยเฉพาะอย่างยิ่งถ้าคุณใช้โซลูชันแบบปิดชั้นวางอย่าขยายบัฟเฟอร์เพียง 1 พิกเซลเพราะขอเพียงพิกเซลเดียว หน่วยความจำที่จัดสรรมีราคาถูก การจัดสรรใหม่การคัดลอกและการปล่อยมีราคาแพง