解决MySql布尔型新旧版本兼容问题,采用枚举来表示布尔型的数据表。由正向工程赋值
大石头 authored at 2018-05-15 21:21:05
5.17 KiB
X
using BenchmarkDotNet.Attributes;
using NewLife.Caching;

namespace Benchmark.CacheBenchmarks;

/// <summary>MemoryCache 单线程基础性能测试</summary>
[MemoryDiagnoser]
[SimpleJob(iterationCount: 3)]
public class MemoryCacheBenchmark
{
    private MemoryCache _cache = null!;
    private String[] _keys = null!;
    private Dictionary<String, String> _batch = null!;

    [Params(1, 10, 100)]
    public Int32 BatchSize { get; set; }

    [GlobalSetup]
    public void Setup()
    {
        _cache = new MemoryCache { Capacity = 0 };

        // 预置100个key,避免Get测试里都是miss
        _keys = new String[100];
        for (var i = 0; i < _keys.Length; i++)
        {
            _keys[i] = $"bench_{i}";
            _cache.Set(_keys[i], $"value_{i}");
        }

        _batch = [];
        for (var i = 0; i < Math.Max(BatchSize, 100); i++)
            _batch[$"batch_{i}"] = $"val_{i}";
    }

    [GlobalCleanup]
    public void Cleanup() => _cache.Dispose();

    // ── 单key操作 ──────────────────────────────────────────────────────────────

    [Benchmark(Description = "Set")]
    public Boolean Set() => _cache.Set("bench_0", "hello");

    [Benchmark(Description = "Get")]
    public String? Get() => _cache.Get<String>("bench_0");

    [Benchmark(Description = "Remove")]
    public Int32 Remove() => _cache.Remove("bench_0");

    [Benchmark(Description = "Inc")]
    public Int64 Inc() => _cache.Increment("counter", 1L);

    // ── 批量操作 ───────────────────────────────────────────────────────────────

    [Benchmark(Description = "SetAll")]
    public void SetAll()
    {
        var dic = new Dictionary<String, String>(BatchSize);
        for (var i = 0; i < BatchSize; i++)
            dic[_keys[i % _keys.Length]] = "v";
        _cache.SetAll(dic);
    }

    [Benchmark(Description = "GetAll")]
    public IDictionary<String, String?> GetAll()
    {
        var keys = _keys.Take(BatchSize);
        return _cache.GetAll<String>(keys);
    }
}

/// <summary>MemoryCache 多线程并发性能测试</summary>
[MemoryDiagnoser]
[SimpleJob(iterationCount: 3)]
public class MemoryCacheConcurrencyBenchmark
{
    private MemoryCache _cache = null!;
    private String[] _keys = null!;

    /// <summary>动态线程数:固定 1/4/8/32,若本机逻辑核心数不在其中则额外加入</summary>
    public static IEnumerable<Int32> ThreadCounts
    {
        get
        {
            var cores = Environment.ProcessorCount;
            var set = new SortedSet<Int32> { 1, 4, 8, 32 };
            set.Add(cores);
            return set;
        }
    }

    [ParamsSource(nameof(ThreadCounts))]
    public Int32 ThreadCount { get; set; }

    [Params(10_000)]
    public Int32 IterationsPerThread { get; set; }

    [GlobalSetup]
    public void Setup()
    {
        _cache = new MemoryCache { Capacity = 0 };
        _keys = new String[64];
        for (var i = 0; i < _keys.Length; i++)
        {
            _keys[i] = $"c_{i}";
            _cache.Set(_keys[i], i.ToString());
        }
    }

    [GlobalCleanup]
    public void Cleanup() => _cache.Dispose();

    [Benchmark(Description = "并发Set-顺序")]
    public void ConcurrentSet_Sequential()
    {
        Parallel.For(0, ThreadCount, t =>
        {
            var myKey = _keys[t % _keys.Length];
            for (var i = 0; i < IterationsPerThread; i++)
                _cache.Set(myKey, "v");
        });
    }

    [Benchmark(Description = "并发Get-顺序")]
    public void ConcurrentGet_Sequential()
    {
        Parallel.For(0, ThreadCount, t =>
        {
            var myKey = _keys[t % _keys.Length];
            for (var i = 0; i < IterationsPerThread; i++)
                _ = _cache.Get<String>(myKey);
        });
    }

    [Benchmark(Description = "并发Remove-顺序")]
    public void ConcurrentRemove_Sequential()
    {
        Parallel.For(0, ThreadCount, t =>
        {
            var myKey = _keys[t % _keys.Length];
            for (var i = 0; i < IterationsPerThread; i++)
                _cache.Remove(myKey);
        });
    }

    [Benchmark(Description = "并发Inc-顺序")]
    public void ConcurrentInc_Sequential()
    {
        Parallel.For(0, ThreadCount, t =>
        {
            var myKey = _keys[t % _keys.Length];
            for (var i = 0; i < IterationsPerThread; i++)
                _cache.Increment(myKey, 1L);
        });
    }

    [Benchmark(Description = "并发Set-随机")]
    public void ConcurrentSet_Random()
    {
        Parallel.For(0, ThreadCount, t =>
        {
            for (var i = t; i < ThreadCount * IterationsPerThread; i += ThreadCount)
                _cache.Set(_keys[i % _keys.Length], "v");
        });
    }

    [Benchmark(Description = "并发Get-随机")]
    public void ConcurrentGet_Random()
    {
        Parallel.For(0, ThreadCount, t =>
        {
            for (var i = t; i < ThreadCount * IterationsPerThread; i += ThreadCount)
                _ = _cache.Get<String>(_keys[i % _keys.Length]);
        });
    }
}