Хранение и поиск двойного массива
Вопрос
У меня есть довольно дорогостоящий расчет массива (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.Гораздо медленнее.
Так это моя реализация неправильная, или я ошибся, что предварительный расчет и поиск выполняются быстрее?
Решение
Вы получаете доступ к LinkedList по индексу, это худший способ доступа к нему;)
Вместо этого вам следует использовать ArrayList или использовать итераторы для всех ваших списков.
Возможно, вам следует объединить три объекта в один и сохранить их на карте с ключом responseNum.
Надеюсь это поможет!
Другие советы
Вероятно, вам следует использовать тип массива (настоящий массив, например Vector, ArrayList), а не связанные списки.Связанные списки лучше всего подходят для работы со стеком или очередью, а не для индексации (поскольку вам придется проходить по ним с одного конца).Vector — это массив с автоматическим изменением размера, который требует меньше накладных расходов при доступе к индексным файлам.
Методы get(i) LinkedList требуют, чтобы для извлечения каждого элемента он перемещался все дальше и дальше по списку.Рассмотрите возможность использования ArrayList, метода iterator() или просто массива.
Вторая строка: 'if (responseNumbers.get(i) == responseNum)
' также будет неэффективным, поскольку responseNumbers.get(i)
является целым числом и должен быть распакован в целое число (Java 5 и более поздние версии делают это автоматически;ваш код не будет компилироваться на Java 1.4 или более ранней версии, если responseNum объявлен как int).Видеть этот дополнительную информацию о боксе.
Чтобы удалить эти накладные расходы на распаковку, используйте ИнтЛист из библиотеки примитивов Apache.Эта библиотека содержит коллекции, в которых хранятся базовые объекты (в вашем случае целые числа) в виде примитивного массива (например,int[]) вместо массива объектов.Это означает, что упаковка не требуется, поскольку методы IntList возвращают примитивные типы, а не целые числа.