Почему, чем больше в моем ключе битов «1», тем больше времени требуется для место в HashMap?

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

Я хотел создать ключ для HashMap , который бы представлял номер строки и столбца элемента таким образом, чтобы при доступе к этой записи на карте я мог повторно извлечь оба ценности. Я не знаю Java так же хорошо, как C # - в C # я бы сделал структуру struct с членами Row и Column , но в Java я быстро понял, что есть нет типов пользовательских значений. С приближением крайнего срока я сделал беспроигрышную ставку и сделал ключ ключом длинным. Я сохранил данные строки (32-битное int) в первых 32 битах и ​​данные столбца в последних 32, используя очень простой сдвиг бит. [РЕДАКТИРОВАТЬ: я также хотел бы отметить, что моя HashMap инициализируется с определенным начальным размером, который точно представляет количество значений, которые я храню в нем, которое никогда не превышается.]

[Дополнительное примечание: я хочу снова получить возможность извлекать данные строки / столбца, чтобы значительно повысить эффективность умножения матриц, с O (n ^ 2) до O (n) и меньший n для загрузки]

. После реализации этой структуры я заметил, что для чтения матрицы 23426 x 23426 из текстового файла в при этом заданы только ненулевые элементы, но вычисление собственных значений, которые мы должны предоставить, занимает всего 2 секунды! После выборочного комментирования методов я пришел к выводу, что большая часть этого 7-секундного промежутка времени уходит на сохранение моих значений в HashMap .

public void Set(double value, int row, int column) {
    //assemble the long key, placing row and column in adjacent sets of bits
    long key = (long)row << SIZE_BIT_MAX; //(SIZE_BIT_MAX is 32)
    key += column;
    elements.put(key, value);
}

Это код для установки значения. Если я воспользуюсь этим методом:

public void Set(double value, int row, int column) {
    //create a distinct but smaller key (around 32 bits max)
    long key = (long)(row * matrixSize) + column;
    elements.put(key, value);
}

Чтение займет всего 2 секунды. Обе эти версии ключа различны для каждого элемента, оба имеют длинный тип, и фактический код для создания любого из них минимален по сложности. Это elements.put (key, value) , который определяет разницу между 7 секундами и 2.

У меня вопрос, почему? Разница, которую я вижу между этими ключевыми версиями, заключается в том, что первая имеет биты, установленные на 1 повсюду и чаще, в то время как вторая имеет все самые высокие 32 бита, установленные на 0. Я преследую отвлекающий маневр, или это довольно резкое различие в производительности результат чего-то внутреннего в методе HashMap.put ?

6
задан A-Type 16 February 2012 в 05:41
поделиться