蛙蛙推荐:并发字典性能测试
测试代码
using System.Collections.Concurrent;
using System.Threading;
using System.Collections.Generic;
using System.Diagnostics;
namespace Test2010 {
static class Perfmon {
public static PerformanceCounter AddCounter;
public static PerformanceCounter RemoveCounter;
public static PerformanceCounter GetOneCounter;
public static void init() {
if (!PerformanceCounterCategory.Exists("conncurrent dict test")) {
CounterCreationDataCollection CCDC = new CounterCreationDataCollection();
CounterCreationData ccd = new CounterCreationData();
ccd.CounterType = PerformanceCounterType.RateOfCountsPerSecond32;
ccd.CounterName = "add/sec";
CCDC.Add(ccd);
ccd = new CounterCreationData();
ccd.CounterType = PerformanceCounterType.RateOfCountsPerSecond32;
ccd.CounterName = "remove/sec";
CCDC.Add(ccd);
ccd = new CounterCreationData();
ccd.CounterType = PerformanceCounterType.RateOfCountsPerSecond32;
ccd.CounterName = "getone/sec";
CCDC.Add(ccd);
PerformanceCounterCategory.Create("conncurrent dict test",
"Demonstrates usage of the AverageCounter64 performance counter type.",
CCDC);
}
AddCounter = new PerformanceCounter("conncurrent dict test", "add/sec", false);
RemoveCounter = new PerformanceCounter("conncurrent dict test", "remove/sec", false);
GetOneCounter = new PerformanceCounter("conncurrent dict test", "getone/sec", false);
AddCounter.RawValue = 0;
RemoveCounter.RawValue = 0;
GetOneCounter.RawValue = 0;
}
}
interface MyDict<K, V> {
void Add(K k, V v);
bool Get(K k, out V v);
bool Remove(K k);
long Count { get; }
}
class ConcurrentDict<K, V> : MyDict<K, V> {
ConcurrentDictionary<K, V> dict = new ConcurrentDictionary<K, V>();
public void Add(K k, V v) {
dict.TryAdd(k, v);
}
public bool Get(K k, out V v) {
V outv = default(V);
bool ret = dict.TryGetValue(k, out outv);
v = outv;
return ret;
}
public bool Remove(K k) {
V outv = default(V);
return dict.TryRemove(k, out outv);
}
public long Count {
get { return dict.Count; }
}
}
class LockDict<K, V> : MyDict<K, V> {
Dictionary<K, V> dict = new Dictionary<K, V>();
public void Add(K k, V v) {
lock (dict)
dict.Add(k, v);
}
public bool Get(K k, out V v) {
V outv = default(V);
bool ret = false;
lock (dict)
ret = dict.TryGetValue(k, out outv);
v = outv;
return ret;
}
public bool Remove(K k) {
lock (dict)
return dict.Remove(k);
}
public long Count {
get {
long ret = 0;
lock (dict)
ret = dict.Count;
return ret;
}
}
}
class RWSLockDict<K, V> : MyDict<K, V> {
Dictionary<K, V> dict = new Dictionary<K, V>();
ReaderWriterLockSlim rwl = new ReaderWriterLockSlim();
public void Add(K k, V v) {
rwl.EnterWriteLock();
try {
dict.Add(k, v);
}
finally {
rwl.ExitWriteLock();
}
}
public bool Get(K k, out V v) {
rwl.EnterReadLock();
bool ret = false;
V outv = default(V);
try {
ret = dict.TryGetValue(k, out outv);
}
finally {
rwl.ExitReadLock();
}
v = outv;
return ret;
}
public bool Remove(K k) {
rwl.EnterWriteLock();
try {
return dict.Remove(k);
}
finally {
rwl.ExitWriteLock();
}
}
public long Count {
get {
rwl.EnterReadLock();
try {
return dict.Count;
}
finally {
rwl.ExitReadLock();
}
}
}
}
class RWLockDict<K, V> : MyDict<K, V> {
Dictionary<K, V> dict = new Dictionary<K, V>();
ReaderWriterLock rwl = new ReaderWriterLock();
public void Add(K k, V v) {
rwl.AcquireWriterLock(Timeout.Infinite);
try {
dict.Add(k, v);
}
finally {
rwl.ReleaseWriterLock();
}
}
public bool Get(K k, out V v) {
rwl.AcquireReaderLock(Timeout.Infinite);
bool ret = false;
V outv = default(V);
try {
ret = dict.TryGetValue(k, out outv);
}
finally {
rwl.ReleaseReaderLock();
}
v = outv;
return ret;
}
public bool Remove(K k) {
rwl.AcquireWriterLock(Timeout.Infinite);
try {
return dict.Remove(k);
}
finally {
rwl.ReleaseWriterLock();
}
}
public long Count {
get {
rwl.AcquireReaderLock(Timeout.Infinite);
try {
return dict.Count;
}
finally {
rwl.ReleaseReaderLock();
}
}
}
}
class Program {
static Dictionary<long, string> dict2 = new Dictionary<long, string>();
static void Main(string[] args) {
Perfmon.init();
//test(new LockDict<long, string>());
//test(new RWLockDict<long, string>());
//test(new RWSLockDict<long, string>());
test(new ConcurrentDict<long, string>());
Console.ReadKey();
}
private static void test(MyDict<long, string> dict) {
new Thread(() => {
long toAdd = 0;
while (true) {
for (int i = 10000 - 1; i >= 0; i--) {
dict.Add(toAdd++, null);
Perfmon.AddCounter.Increment();
}
Thread.Sleep(0);
}
}).Start();
new Thread(() => {
long toGet = 0;
while (true) {
for (int i = 10000 - 1; i >= 0; i--) {
string value = null;
if (dict.Get(toGet++, out value))
Perfmon.GetOneCounter.Increment();
else
Thread.Sleep(0);
}
}
}).Start();
new Thread(() => {
long toRemove = 0;
while (true) {
for (int i = 10000 - 1; i >= 0; i--) {
if (dict.Remove(toRemove++))
Perfmon.RemoveCounter.Increment();
else
Thread.Sleep(0);
}
}
}).Start();
new Thread(() => {
while (true) {
Thread.Sleep(1 * 1000);
float addspeed = Perfmon.AddCounter.NextValue();
float removespeed = Perfmon.RemoveCounter.NextValue();
float getspeed = Perfmon.GetOneCounter.NextValue();
Console.WriteLine("count:{0},addspeed:{1},removespeed:{2},getspeed:{3}",
dict.Count, addspeed, removespeed, getspeed);
if (Process.GetCurrentProcess().PrivateMemorySize64 > 500 * 1000 * 1000)
Debugger.Break();
}
}).Start();
}
}
}
测试结果
Moniter
count:105045,addspeed:0,removespeed:0,getspeed:0
count:126415,addspeed:2349041,removespeed:2358700,getspeed:0.991922
count:152102,addspeed:2460776,removespeed:2436386,getspeed:0
count:180880,addspeed:2434290,removespeed:2405377,getspeed:0.9986522
count:208087,addspeed:2356795,removespeed:2329853,getspeed:0.9993654
count:235697,addspeed:2381048,removespeed:2359981,getspeed:0
count:255639,addspeed:2330674,removespeed:2304021,getspeed:7363.678
count:282080,addspeed:2342998,removespeed:2317704,getspeed:0
count:308603,addspeed:2297925,removespeed:2270916,getspeed:0
count:351934,addspeed:2243886,removespeed:2199811,getspeed:0
count:384852,addspeed:2191864,removespeed:2163686,getspeed:0
count:411401,addspeed:2165051,removespeed:2136198,getspeed:0
count:439602,addspeed:2105852,removespeed:2077565,getspeed:0.9964557
count:463202,addspeed:2178960,removespeed:2147194,getspeed:338.0086
ReaderWriterLock
count:54837,addspeed:0,removespeed:0,getspeed:0
count:60702,addspeed:1602391,removespeed:1632856,getspeed:0
count:60103,addspeed:1632617,removespeed:1632556,getspeed:0
count:67684,addspeed:1625243,removespeed:1600775,getspeed:0
count:60751,addspeed:1614181,removespeed:1649622,getspeed:0.9784912
count:62254,addspeed:1648427,removespeed:1628174,getspeed:0
count:65441,addspeed:1629013,removespeed:1632586,getspeed:0
count:61718,addspeed:1619081,removespeed:1632310,getspeed:0
count:69004,addspeed:1620137,removespeed:1601762,getspeed:0.9838534
count:70127,addspeed:1631347,removespeed:1632016,getspeed:0
count:69086,addspeed:1603095,removespeed:1604241,getspeed:0
count:71313,addspeed:1593107,removespeed:1590229,getspeed:0
count:71054,addspeed:1583672,removespeed:1582212,getspeed:0
ReaderWriterLockSlim
count:88076,addspeed:0,removespeed:0,getspeed:0
count:111783,addspeed:1808608,removespeed:1805854,getspeed:13623.26
count:134402,addspeed:1847843,removespeed:1826155,getspeed:0
count:247921,addspeed:1869431,removespeed:1755994,getspeed:613.397
count:140291,addspeed:1777865,removespeed:1887006,getspeed:2760.325
count:175310,addspeed:1741924,removespeed:1704160,getspeed:0
count:191920,addspeed:1760130,removespeed:1745391,getspeed:0
count:279151,addspeed:1735299,removespeed:1648902,getspeed:12872.49
count:284211,addspeed:1705305,removespeed:1695007,getspeed:2508.193
count:268290,addspeed:1854861,removespeed:1874381,getspeed:0
count:253860,addspeed:1883145,removespeed:1899016,getspeed:0
count:345832,addspeed:1910205,removespeed:1818164,getspeed:0
count:332211,addspeed:1862118,removespeed:1874364,getspeed:0
count:335086,addspeed:1759834,removespeed:1749731,getspeed:0
count:297357,addspeed:1766702,removespeed:1811752,getspeed:0
ConcurrentDictionary
count:149733,addspeed:0,removespeed:0,getspeed:0
count:165362,addspeed:3157740,removespeed:3184047,getspeed:0.9946244
count:156885,addspeed:3233400,removespeed:3242754,getspeed:0
count:182704,addspeed:3267045,removespeed:3241828,getspeed:0
count:161199,addspeed:3246324,removespeed:3268855,getspeed:0
count:197373,addspeed:3252242,removespeed:3216067,getspeed:0
count:172697,addspeed:2923975,removespeed:2946616,getspeed:0.9809359
count:168771,addspeed:3162394,removespeed:3169271,getspeed:0
count:171764,addspeed:3251227,removespeed:3245190,getspeed:0
count:174449,addspeed:3192373,removespeed:3190920,getspeed:0
count:164198,addspeed:3016690,removespeed:3026149,getspeed:0
count:198603,addspeed:3220062,removespeed:3185224,getspeed:0
count:243862,addspeed:3078294,removespeed:3034764,getspeed:0
count:248862,addspeed:3031934,removespeed:3025461,getspeed:0.9905463
count:251690,addspeed:2965359,removespeed:2962356,getspeed:0