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

namespace Benchmark.StreamingBenchmarks;

/// <summary>会话流式发送基准:SendAsync(Stream) 管道路径 / 手工分块 Send / 整段 Send(回环 TCP)</summary>
/// <remarks>
/// 命令:dotnet run --project Benchmark/Benchmark.csproj -c Release -- --filter "*SessionStreamBenchmark*"
/// 服务端仅接收计数不回发;客户端与服务器共享 CPU(loopback 口径)。
/// </remarks>
[MemoryDiagnoser]
[SimpleJob(warmupCount: 2, iterationCount: 5)]
public class SessionStreamBenchmark : IDisposable
{
    private ThroughputNetServer _server = null!;
    private TcpSession _client = null!;
    private Byte[] _payload = null!;
    private MemoryStream _stream = null!;

    /// <summary>单次发送总字节数</summary>
    [Params(1024 * 1024, 8 * 1024 * 1024)]
    public Int32 Size { get; set; }

    [GlobalSetup]
    public void Setup()
    {
        _server = new ThroughputNetServer
        {
            Port = 0,
            ProtocolType = NetType.Tcp,
            AddressFamily = AddressFamily.InterNetwork,
            UseSession = false,
        };
        _server.Start();

        var uri = new NetUri($"tcp://127.0.0.1:{_server.Port}");
        var client = uri.CreateRemote();
        client.Open();
        _client = (TcpSession)client;

        _payload = new Byte[Size];
        Random.Shared.NextBytes(_payload);
        _stream = new MemoryStream(_payload);
    }

    [GlobalCleanup]
    public void Cleanup()
    {
        _client?.Dispose();
        _server?.Dispose();
    }

    /// <summary>清理</summary>
    public void Dispose() => Cleanup();

    /// <summary>流式发送:SendAsync(Stream) 分块零拷贝入管道 + 写侧回压</summary>
    [Benchmark]
    public async Task<Int64> SendAsyncStream()
    {
        _server.Reset(Size);
        _stream.Position = 0;

        await _client.SendAsync(_stream, Size);
        if (!_server.WaitComplete(120_000)) throw new TimeoutException("SendAsync 超时");

        return _server.ReceivedBytes;
    }

    /// <summary>手工分块:16KB 小块循环 Send(Byte[], offset, count)(传统写法,无管道)</summary>
    [Benchmark]
    public Int64 ManualChunks()
    {
        _server.Reset(Size);

        const Int32 chunk = 16 * 1024;
        for (var offset = 0; offset < Size; offset += chunk)
        {
            var count = Math.Min(chunk, Size - offset);
            _client.Send(_payload, offset, count);
        }

        if (!_server.WaitComplete(120_000)) throw new TimeoutException("手工分块超时");

        return _server.ReceivedBytes;
    }

    /// <summary>手工分块:64KB 大块循环(测分块粒度敏感性)</summary>
    [Benchmark]
    public Int64 ManualChunks64K()
    {
        _server.Reset(Size);

        const Int32 chunk = 64 * 1024;
        for (var offset = 0; offset < Size; offset += chunk)
        {
            var count = Math.Min(chunk, Size - offset);
            _client.Send(_payload, offset, count);
        }

        if (!_server.WaitComplete(120_000)) throw new TimeoutException("手工分块64K超时");

        return _server.ReceivedBytes;
    }

    /// <summary>整段发送:一次 Send(Byte[])(内核自行分段)</summary>
    [Benchmark]
    public Int64 WholeSend()
    {
        _server.Reset(Size);

        _client.Send(_payload);

        if (!_server.WaitComplete(120_000)) throw new TimeoutException("整段发送超时");

        return _server.ReceivedBytes;
    }
}