2016-12-17 2 views
0

В Java, насколько больше памяти (байты) является потреблением LinkedHashSet по сравнению с «обычным» HashSet? Я знаю, что LinkedHashSet немного медленнее для определенных операций, но как насчет использования памяти?LinkedHashSet vs Потребление памяти HashSet

+0

Не видя обмана там @Bruno_Ferreira – pvg

+0

Вероятно, стоимость пары указателей и заголовка списка. Вы проверили источник реализации на [GrepCode] (http://grepcode.com)? –

ответ

3

https://github.com/DimitrisAndreou/memory-measurer/blob/master/ElementCostInDataStructures.txt

HashSet составляет ~ 32 байт/элемент; a LinkedHashSet - ~ 40 байт/элемент.

+0

Для 64-битных JDK, которые, вероятно, предполагают, что 'CompressedOops' активен, но это должно быть так, пока вы не нажмете> 32 ГБ кучи, по крайней мере, на Hotspot. – BeeOnRope

+0

Вы уверены, что будете использовать это, так что да, это должно быть наиболее реалистичное число для большинства сценариев. –

+0

Да, это по умолчанию, поэтому большинство людей используют его независимо от того, знают они это или нет. Это возможно: кто-то, кто заботится о использовании памяти связанными узлами, использует гигантскую кучу. – BeeOnRope

2

Как следует из названия, и в документе указано явно, LinkedHashSet, кроме ядра HashSet, необходимо поддерживать связанный список. Я думаю, что можно с уверенностью предположить, что верхняя граница потребления памяти может быть аппроксимирована, как если бы у вас было всего две отдельные структуры данных: хэш-набор и связанный список. Сколько они потребляют память, это отдельный вопрос.

Однако, если вам нужны жесткие данные о количестве используемых байт памяти, вы всегда можете выполнить некоторые тесты самостоятельно. Это не должно быть слишком сложно проверить или google на некоторое время - я уверен, что в Интернете уже есть некоторые результаты тестов.

@edit, после того, как ответ Луи

казалось мне интересно, почему разница меньше. Вот простой тест я писал:

package com.company; 

import com.javamex.classmexer.MemoryUtil; 

import java.util.HashSet; 
import java.util.LinkedHashSet; 
import java.util.Random; 

public class Main 
{ 
    public static void main(String[] args) 
    { 
     // Creating data structures under test ------- 
     HashSet<Integer> hashSet = new HashSet<>(); 

     Random random = new Random(); 
     for (int i=0; i<1000000; i++) 
     { 
      hashSet.add(random.nextInt()); 
     } 

     LinkedHashSet<Integer> linkedHashSet = new LinkedHashSet<>(hashSet); 

     // Measuring memory usage -------------------- 
     long sizeOfHashSet = MemoryUtil.deepMemoryUsageOf(hashSet); 
     long sizeOfLinkedHashSet = MemoryUtil.deepMemoryUsageOf(linkedHashSet); 
     System.out.println("Size of HashSet:\n" + sizeOfHashSet + " B"); 
     System.out.println("Size of LinkedHashSet:\n" + sizeOfLinkedHashSet + " B"); 
     System.out.println("LinkedHashSet is bigger from HashSet by " + (sizeOfLinkedHashSet*100/sizeOfHashSet - 100) + "%"); 

     System.out.println("\n"); 

     long numberOfElements = hashSet.size(); 
     System.out.println("Number of elements in the test HashSet: " + numberOfElements); 

     System.out.println("Average size of a single element in HashSet: " + sizeOfHashSet/numberOfElements + " B"); 
     System.out.println("Average size of a single element in LinkedHashSet: " + sizeOfLinkedHashSet/numberOfElements + " B"); 
    } 
} 

После того, как работает его несколько раз я заметил, что выводит стабильные результаты сказочные (размеры объекта отличаются +/- 2 KiB), который я представляю ниже:

Size of HashSet: 
56347616 B 
Size of LinkedHashSet: 
64348040 B 
LinkedHashSet is bigger from HashSet by 14% 

Number of elements in the test HashSet: 999876 
Average size of a single element in HashSet: 56 B 
Average size of a single element in LinkedHashSet: 64 B 

Что интересно, оно не соответствует значениям, данным Луи. Однако разница в байтах на элемент такая же, как писал Луи (8 B). Может ли кто-то объяснить несоответствие ценностям? Я измеряю размер объекта неправильно?

+2

'HashSet' - 32 байта/элемент; 'LinkedList' - 24 байта/элемент,' LinkedHashSet' - 40 байт/элемент. Они не просто добавляют. –

+0

могут быть различия в работе в 32-разрядной и 64-разрядной JVM, с или без «CompressedOops» и т. Д. –

Смежные вопросы