JAVA: Set lepszy do .contain niż ArrayList
Dzisiaj takie święto, więc przy okazji - a w zasadzie to bez okazji, ale święto jest ;) - napiszę o takiej ciekawostce jak z tytułu.
Zebrałem ciekawe wypowiedzi stąd:
A tu jest kodzik do testowania:
Bardzo mnie interesuje co o tym sądzisz, dlatego byłoby mi miło, jeśli byś napisał w komentarzu coś o tym, może być cokolwiek :)
Zebrałem ciekawe wypowiedzi stąd:
The set will give much better performance (O(n)vsO(n^2)for the list), and that's normal because set membership (thecontainsoperation) is the very purpose of a set.
Contains for aHashSetisO(1)compared toO(n)for a list, therefore you should never use a list if you often need to runcontains.
I've made a test so please check the result:
For SAME STRING items in a HashSet, TreeSet, ArrayList and LinkedList, here are the results for
1. 50.000 UUIDs
- SEARCHED ITEM : e608c7d5-c861-4603-9134-8c636a05a42b (index 25.000)
- hashSet.contains(item) ? TRUE 0 ms
- treeSet.contains(item) ? TRUE 0 ms
- arrayList.contains(item) ? TRUE 2 ms
- linkedList.contains(item) ? TRUE 3 ms
2. 5.000.000 UUIDs
- SEARCHED ITEM : 61fb2592-3186-4256-a084-6c96f9322a86 (index 25.000)
- hashSet.contains(item) ? TRUE 0 ms
- treeSet.contains(item) ? TRUE 0 ms
- arrayList.contains(item) ? TRUE 1 ms
- linkedList.contains(item) ? TRUE 2 ms
3. 5.000.000 UUIDs
- SEARCHED ITEM : db568900-c874-46ba-9b44-0e1916420120 (index 2.500.000)
- hashSet.contains(item) ? TRUE 0 ms
- treeSet.contains(item) ? TRUE 0 ms
- arrayList.contains(item) ? TRUE 33 ms
- linkedList.contains(item) ? TRUE 65 ms
Based on above results, there is NOT a BIG difference of using array list vs set. Perhaps you can try to modify this code and replace the String with your Object and see the differences then...
A tu jest kodzik do testowania:
    public static void main(String[] args) {
        Set<String> hashSet = new HashSet<>();
        Set<String> treeSet = new TreeSet<>();
        List<String> arrayList = new ArrayList<>();
        List<String> linkedList = new LinkedList<>();
        List<String> base = new ArrayList<>();
        for(int i = 0; i<5000000; i++){
            if(i%100000==0) System.out.print(".");
            base.add(UUID.randomUUID().toString());
        }
        System.out.println("\nBase size : " + base.size());
        String item = base.get(25000);
        System.out.println("SEARCHED ITEM : " + item);
        hashSet.addAll(base);
        treeSet.addAll(base);
        arrayList.addAll(base);
        linkedList.addAll(base);
        long ms = System.currentTimeMillis();
        System.out.println("hashSet.contains(item) ? " + (hashSet.contains(item)? "TRUE " : "FALSE") + (System.currentTimeMillis()-ms) + " ms");
        System.out.println("treeSet.contains(item) ? " + (treeSet.contains(item)? "TRUE " : "FALSE") + (System.currentTimeMillis()-ms) + " ms");
        System.out.println("arrayList.contains(item) ? " + (arrayList.contains(item)? "TRUE " : "FALSE") + (System.currentTimeMillis()-ms) + " ms");
        System.out.println("linkedList.contains(item) ? " + (linkedList.contains(item)? "TRUE " : "FALSE") + (System.currentTimeMillis()-ms) + " ms");
    }Bardzo mnie interesuje co o tym sądzisz, dlatego byłoby mi miło, jeśli byś napisał w komentarzu coś o tym, może być cokolwiek :)
Powinno być contains(). Test ok, ale jego wyniki są raczej źle zinterpretowane, bo dla 5 milionów elementów jedna operacja contains() dla list trwa 33ms i 65ms, a dla Set 0ms, to kolosalna różnica. Również dla 50000 elementów widać różnicę, która przy wielu takich operacjach mogłaby dać o sobie znać.
OdpowiedzUsuń