Хранение и поиск двойного массива - PullRequest
1 голос
/ 11 декабря 2008

У меня довольно дорогой расчет массива (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 прямо. Намного медленнее.

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

Ответы [ 4 ]

4 голосов
/ 11 декабря 2008

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

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

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

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

1 голос
/ 11 декабря 2008

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

1 голос
/ 11 декабря 2008

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

0 голосов
/ 18 декабря 2008

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...