Dengan tangan
Jika memori bukan sumber daya yang sangat jarang, saya menganggap bekerja di potongan yang lebih besar.
Berikut ini beberapa kode semu.
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;
}
}
Implementasi ini cukup naif.
Untuk satu, itu menciptakan potongan di getPixel (pada dasarnya itu akan baik-baik saja untuk mengembalikan 0 atau lebih, jika tidak ada potongan didefinisikan untuk posisi itu). Kedua didasarkan pada asumsi, bahwa Anda memiliki implementasi Peta yang cukup cepat dan terukur. Setahu saya setiap bahasa yang baik memiliki satu.
Anda juga harus bermain dengan ukuran chunk. Untuk bitmap yang padat, ukuran chunk yang besar adalah baik, untuk bitmap yang jarang, ukuran chunk yang lebih kecil lebih baik. Bahkan untuk yang sangat jarang, "ukuran chunk" dari 1 adalah yang terbaik, menjadikan "chunk" itu sendiri usang dan mengurangi struktur data menjadi peta int dari peta piksel int.
Dari rak
Solusi lain mungkin dengan melihat beberapa perpustakaan grafis. Mereka sebenarnya cukup bagus dalam menggambar satu buffer 2D ke yang lain. Itu berarti Anda hanya akan mengalokasikan buffer yang lebih besar dan memiliki yang asli ditarik ke dalamnya di koordinat yang sesuai.
Sebagai strategi umum: Ketika memiliki "blok memori yang tumbuh secara dinamis", adalah ide yang baik untuk mengalokasikan beberapa dari itu, setelah digunakan. Ini agak menghabiskan banyak memori, tetapi secara signifikan memotong alokasi dan biaya penyalinan . Sebagian besar implementasi vektor mengalokasikan dua kali ukurannya, ketika terlampaui. Jadi terutama jika Anda menggunakan solusi yang tidak tersedia, jangan memperpanjang buffer Anda hanya dengan 1 pixel, karena hanya satu pixel yang diminta. Memori yang dialokasikan murah. Realokasi, menyalin, dan melepaskan itu mahal.