Хранение и поиск двойного массива

У меня есть довольно дорогой расчет массива (SpectralResponse), который я хотел бы свести к минимуму. Я решил, что лучший способ - это сохранить их и восстановить, когда в будущем снова понадобится тот же массив. Решение принимается с использованием BasicParameters.

Поэтому сейчас я использую LinkedList объекта для массивов SpectralResponse и еще один LinkedList для BasicParameter. И у BasicParameters есть метод isParamsEqualTo (BasicParameters) для сравнения набора параметров.

LinkedList<SpectralResponse> responses
LinkedList<BasicParameters> fitParams
LinkedList<Integer> responseNumbers

Итак, чтобы посмотреть, я просто просматриваю список BasicParameters, проверяю соответствие, если совпадают, возвращаю SpectralResponse. Если совпадений нет, то рассчитайте SpectralResponse.

Вот цикл for, который я использовал для поиска.

size: LinkedList size, limited to a reasonable value
responseNumber: just another variable to distinguish the SpectralResponse.

    for ( i = size-1; i > 0 ; i--) {
        if (responseNumbers.get(i) == responseNum)
        {
            tempFit = fitParams.get(i);
            if (tempFit.isParamsEqualTo(fit))
            {
                return responses.get(i);
            }
        }
    }

Но почему-то, делая это таким образом, вы не только отнимаете много памяти, но на самом деле медленнее, чем просто вычисление SpectralResponse прямо. Намного медленнее

Так что это моя реализация не так, или я ошибся, что предварительный расчет и поиск быстрее?

11.12.2008 08:57:42
Ваш цикл не проверяет индекс 0, измените его на: for (i = size-1; i> = 0; i--) {}
refrus 11.12.2008 09:07:47
4 ОТВЕТА
РЕШЕНИЕ

Вы получаете доступ к LinkedList по индексу, это худший из возможных способов получить к нему доступ;)

Вместо этого вы должны использовать ArrayList или использовать итераторы для всех ваших списков.

Возможно, вам следует объединить три объекта в один и сохранить их на карте с ключом responseNum.

Надеюсь это поможет!

4
11.12.2008 09:01:57
Взял ваш совет и использовал HashMap и поместил BasicParameter и responseNumber в один объект вместо ключа карты запроса, теперь он в 100 раз быстрее.
Dan 11.12.2008 13:43:36

Вы, вероятно, должны использовать тип массива (фактический массив, такой как Vector, ArrayList), а не связанные списки. Связанные списки лучше всего подходят для операций со стеком или очередью, а не для индексации (так как вы должны обходить их с одного конца). Vector - это массив с автоматическим изменением размера, который имеет меньше затрат при доступе к файлам EXE.

1
11.12.2008 09:03:53
Я бы посоветовал ArrayList поверх Vector, особенно если у вас большой набор данных. Вектор синхронизирован, что снижает производительность.
GaryF 11.12.2008 09:07:10

Методы get (i) LinkedList требуют, чтобы для извлечения каждого элемента он шел дальше и дальше по списку. Попробуйте использовать ArrayList, метод iterator () или просто массив.

1
11.12.2008 09:06:12

Вторая строка ' if (responseNumbers.get(i) == responseNum)' также будет неэффективна, так как responseNumbers.get(i)является целым числом, и ее необходимо распаковать в int (Java 5 и далее делает это автоматически; ваш код не будет компилироваться на Java 1.4 или более ранней, если responseNum объявлен как int ). Смотрите это для получения дополнительной информации о боксе.

Чтобы удалить эти издержки распаковки, используйте IntList из библиотеки примитивов apache. Эта библиотека содержит коллекции, которые хранят базовые объекты (целые числа в вашем случае) в виде примитивного массива (например, int []) вместо массива объектов. Это означает, что бокс не требуется, поскольку методы IntList возвращают примитивные типы, а не целые числа.

0
17.12.2008 22:11:55