Когда я должен использовать ConcurrentSkipListMap?

В Java ConcurrentHashMap для лучшего multithreading решение. Тогда когда я должен использовать ConcurrentSkipListMap? Это избыточность?

Являются ли аспекты многопоточности общими для этих двух?

64 голоса | спросил DKSRathore 28 62009vEurope/Moscow11bEurope/MoscowSat, 28 Nov 2009 09:33:25 +0300 2009, 09:33:25

3 ответа


0

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

ConcurrentHashMap выполняет не гарантирует * время выполнения своих операций в рамках своего контракта. Это также позволяет настраивать определенные коэффициенты загрузки (примерно, количество потоков, одновременно изменяющих его).

На странице ---- +: = 0 =: + ---- также имеет ряд операций, которые ConcurrentSkipListMap не: terraceEntry /Key, floorEntry /Key и т. д. Он также поддерживает порядок сортировки, который в противном случае должен был бы быть рассчитан (при значительных затратах), если бы вы использовали ConcurrentHashMap

В основном, разные реализации предоставляются для разных вариантов использования. Если вам нужно быстрое добавление пары «один ключ /значение» и быстрый поиск по одной клавише, используйте ConcurrentHashMap. Если вам нужен более быстрый обход заказа и вы можете позволить себе дополнительные затраты на вставку, используйте HashMap.

* Хотя я ожидаю, что реализация примерно соответствует общим гарантиям хеш-карты для вставки /поиска O (1); игнорирование повторного хеширования

ответил Kevin Montrose 28 62009vEurope/Moscow11bEurope/MoscowSat, 28 Nov 2009 09:50:03 +0300 2009, 09:50:03
0

См. Список пропуска для определения структуры данных. ConcurrentSkipListMap хранит карту в естественном порядке ее ключей (или в другом определенном вами порядке ключей). Так что он будет иметь более медленные операции get /put /contains, чем HashMap, но для компенсации этого он поддерживает интерфейсы SortedMap и NavigableMap.

ответил Jim Ferrans 28 62009vEurope/Moscow11bEurope/MoscowSat, 28 Nov 2009 09:48:45 +0300 2009, 09:48:45
0

С точки зрения производительности skipList при использовании в качестве карты - кажется в 10-20 раз медленнее. Вот результат моих тестов (Java 1.8.0_102-b14, win x32)

Benchmark                    Mode  Cnt  Score    Error  Units
MyBenchmark.hasMap_get       avgt    5  0.015 ?  0.001   s/op
MyBenchmark.hashMap_put      avgt    5  0.029 ?  0.004   s/op
MyBenchmark.skipListMap_get  avgt    5  0.312 ?  0.014   s/op
MyBenchmark.skipList_put     avgt    5  0.351 ?  0.007   s/op

И в дополнение к этому - вариант использования, где сравнение одного с другим действительно имеет смысл. Реализация кэша последних недавно использованных элементов с использованием обеих этих коллекций. Теперь эффективность skipList выглядит как событие более сомнительное.

MyBenchmark.hashMap_put1000_lru      avgt    5  0.032 ?  0.001   s/op
MyBenchmark.skipListMap_put1000_lru  avgt    5  3.332 ?  0.124   s/op

Вот код для JMH (выполняется как java -jar target/benchmarks.jar -bm avgt -f 1 -wi 5 -i 5 -t 1)

static final int nCycles = 50000;
static final int nRep = 10;
static final int dataSize = nCycles / 4;
static final List<String> data = new ArrayList<>(nCycles);
static final Map<String,String> hmap4get = new ConcurrentHashMap<>(3000, 0.5f, 10);
static final Map<String,String> smap4get = new ConcurrentSkipListMap<>();

static {
    // prepare data
    List<String> values = new ArrayList<>(dataSize);
    for( int i = 0; i < dataSize; i++ ) {
        values.add(UUID.randomUUID().toString());
    }
    // rehash data for all cycles
    for( int i = 0; i < nCycles; i++ ) {
        data.add(values.get((int)(Math.random() * dataSize)));
    }
    // rehash data for all cycles
    for( int i = 0; i < dataSize; i++ ) {
        String value = data.get((int)(Math.random() * dataSize));
        hmap4get.put(value, value);
        smap4get.put(value, value);
    }
}

@Benchmark
public void skipList_put() {
    for( int n = 0; n < nRep; n++ ) {
        Map<String,String> map = new ConcurrentSkipListMap<>();

        for( int i = 0; i < nCycles; i++ ) {
            String key = data.get(i);
            map.put(key, key);
        }
    }
}

@Benchmark
public void skipListMap_get() {
    for( int n = 0; n < nRep; n++ ) {
        for( int i = 0; i < nCycles; i++ ) {
            String key = data.get(i);
            smap4get.get(key);
        }
    }
}

@Benchmark
public void hashMap_put() {
    for( int n = 0; n < nRep; n++ ) {
        Map<String,String> map = new ConcurrentHashMap<>(3000, 0.5f, 10);

        for( int i = 0; i < nCycles; i++ ) {
            String key = data.get(i);
            map.put(key, key);
        }
    }
}

@Benchmark
public void hasMap_get() {
    for( int n = 0; n < nRep; n++ ) {
        for( int i = 0; i < nCycles; i++ ) {
            String key = data.get(i);
            hmap4get.get(key);
        }
    }
}

@Benchmark
public void skipListMap_put1000_lru() {
    int sizeLimit = 1000;

    for( int n = 0; n < nRep; n++ ) {
        ConcurrentSkipListMap<String,String> map = new ConcurrentSkipListMap<>();

        for( int i = 0; i < nCycles; i++ ) {
            String key = data.get(i);
            String oldValue = map.put(key, key);

            if( (oldValue == null) && map.size() > sizeLimit ) {
                // not real lru, but i care only about performance here
                map.remove(map.firstKey());
            }
        }
    }
}

@Benchmark
public void hashMap_put1000_lru() {
    int sizeLimit = 1000;
    Queue<String> lru = new ArrayBlockingQueue<>(sizeLimit + 50);

    for( int n = 0; n < nRep; n++ ) {
        Map<String,String> map = new ConcurrentHashMap<>(3000, 0.5f, 10);

        lru.clear();
        for( int i = 0; i < nCycles; i++ ) {
            String key = data.get(i);
            String oldValue = map.put(key, key);

            if( (oldValue == null) && lru.size() > sizeLimit ) {
                map.remove(lru.poll());
                lru.add(key);
            }
        }
    }
}
ответил Xtra Coder 15 thEurope/Moscowp30Europe/Moscow09bEurope/MoscowThu, 15 Sep 2016 11:53:04 +0300 2016, 11:53:04

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132