Многомерные байтовые массивы с LinkedHashMap ... Есть ли лучший способ? - PullRequest
4 голосов
/ 21 декабря 2010

Я ОЧЕНЬ новичок в программировании на Java, поэтому, пожалуйста, прости мои вопросы для новичков:).

Я использую LinkedHashMap в качестве файлового кеша для приложения, которое я изменяю ради помощи в разработке.Я делаю это, чтобы уменьшить накладные расходы ввода-вывода и, следовательно, повысить производительность.Проблема в том, что накладные расходы вводятся многими другими способами.

Соответствующий источник выглядит следующим образом.


// Retrieve Data From LinkedHashMap  
byte grid[][][] = null;  
if(file.exists())
{  
    if (!cache.containsKey(file))  
    {
        FileInputStream fis = new FileInputStream(file);
        BufferedInputStream bis = new BufferedInputStream(fis, 16384);
        ObjectInputStream ois = new ObjectInputStream(bis);
        cache.put(file, ois.readObject());
        ois.close();
    }
    grid = (byte[][][]) cache.get(file);
} else {
    grid = new byte[8][8][];
}

Ниже приводится то, что я использую для сохранения данных.Метод загрузки данных является совершенно противоположным.


ByteArrayOutputStream baos = new ByteArrayOutputStream();
GZIPOutputStream gos = new GZIPOutputStream(baos){{    def.setLevel(2);}};
BufferedOutputStream bos = new BufferedOutputStream(gos, 16384);
DataOutputStream dos = new DataOutputStream(bos);
// Some code writes to dos
dos.close();
byte[cx][cz] = baos.toByteArray();
baos.close();
cache.put(file, grid);

А вот и объявление для кэша.


private static LinkedHashMap<File, Object> cache = new LinkedHashMap<File, Object>(64, 1.1f, true)
{protected boolean removeEldestEntry(Map.Entry<File, Object> eldest) 
    {
        return size() > 64;
    }
}

Поскольку я очень незнаком с этикетом Java-потока, весьма вероятно, что приведенный выше код выглядит неаккуратно.Я также уверен, что есть более эффективные способы сделать это, например, куда поместить буфер.

В любом случае, моя основная проблема заключается в следующем: всякий раз, когда мне нужно что-то сделать с одним чанком, у меня естьпреобразовать все данные сетки в объект, отправить его в кеш и записать файл.Это очень неэффективный способ ведения дел.Я хотел бы знать, есть ли лучший способ сделать это, чтобы мне не нужно было получать ();весь массив байтов [8] [8] [], когда мне нужен только доступ к этому одному чанку.Я хотел бы сделать что-то вроде chunk = cache.get [cx] cz, но я уверен, что это не так просто.

В любом случае, как я уже говорил ранее, прошу прощения за вопрос, если ответочевидно, я всего лишь скромный новичок: D.Я очень ценю любой вклад:).

Спасибо.

Ответы [ 2 ]

1 голос
/ 22 декабря 2010

Если ваша цель - уменьшить накладные расходы ввода-вывода, как насчет размещения объекта byte[][][] в объект-обертку, который добавляет концепцию грязного флага?

Таким образом, вы можете уменьшить количество раз, когда файл записывается после модификации, записывая грязные объекты на диск только тогда, когда вы либо используете кеш, либо собираетесь удалить старший объект при вставке в кеш. 1004 *

0 голосов
/ 22 декабря 2010

Я бы начал с создания нового класса - назовите его ByteMatrix3D - для хранения данных.И вместо использования byte[][][], я бы использовал одномерный массив с вычисленными смещениями (например, в массиве 8x8x8 смещение [1][2][3] может быть вычислено как 1 * 64 + 2 * 8 + 3. Это изменение устранит немалонакладные расходы на управление объектами, а также позволяют вносить дополнительные изменения, не влияя на код более высокого уровня.

И первое, что я хотел бы сделать, это использовать MappedByteBuffer для доступа к файлам.пусть операционная система управляет фактическими данными и делает чтение и запись прозрачными для программы.

...