编写一个并发性能测试的小程序

1,090 阅读2分钟

这是我参与8月更文挑战的第31天,活动详情查看:8月更文挑战

  • 📢欢迎点赞 :👍 收藏 ⭐留言 📝 如有错误敬请指正,赐人玫瑰,手留余香!
  • 📢本文作者:由webmote 原创,首发于 【掘金】
  • 📢作者格言: 生活在于折腾,当你不折腾生活时,生活就开始折腾你,让我们一起加油!💪💪💪

1.为了统计qps,我使用了Interlocked锁

是的,是锁总会有损耗,因为使用了Interlocked锁的缘故,肯定会对性能测试造成一定的干扰,那我们先来看看底噪是多少,开100个线程,写个什么都不干的函数,开始run。

image.png

cpu跑满了,火力全开,qps达到了1.1亿, 哦哦哦,我想我可以忽略这个影响了,你说是吧。

2编写qps计数

这里记录了qps、error、threads以及时间, 为了不再开启线程和省事,甚至还增加了一个按照时间秒数打印输出日志的功能。

一切就是这么简单。

这是定义:

private volatile int Qps = 0;
private volatile int Error = 0;
private volatile int Threads = 0;
private DateTime dtStart = DateTime.Now;
private volatile int printSecond = 1;

我们提供个接口,增加qps计数

public void AddQps()
{
    Interlocked.Increment(ref Qps);
    Print();
}

到整数时间就打印

if(Seconds == Interlocked.Exchange(ref printSecond,Seconds+1))
{
    Console.WriteLine($"time={Seconds}, threads= {MyThreads}, qps = {MyQps}, error = {MyError}");
}

增加错误,和线程数,类似增加qps接口。

提供访问qps等的属性:

public int Seconds => (int)((DateTime.Now - dtStart).TotalSeconds);
public int MyQps => Qps / (Seconds==0 ? 1: Seconds);
public int MyError => Error / (Seconds == 0 ? 1 : Seconds);
public int MyThreads => Threads ;

3 使用计数

在我们内部的测试用例内,我们需要调用计数类的增加qps等接口,这个计数类是全局的,各个线程共享计数类实例。

private void internalTest()
{
    var idx = random.Next(0, actions.Count);
    try
    {
        actions[idx].Invoke();
    }
    catch (Exception ex)
    {
        calcValue.AddError();
    }
    finally
    {
        calcValue.AddQps();
    }
}

4.并发线程测试

循环新建线程类,并在线程体内塞入单个的测试用例,以及全局的计数类。在建立好所有的线程后,耗时不计入性能的计算都预热好,然后一块开启线程,开始测试。

为了让性能测试更充分,我编写了不同的计算过程,并使用随机函数随机获取并塞入线程执行。

当然一切搞定后,调用就非常简单了。

var test = new ParallelTest(nThread);
test.Start<UTest1>(TimeSpan.FromSeconds(nSpan));

当然.net core 开启线程池限制, 避免性能问题。

 ThreadPool.SetMinThreads(1000, 1000);
 ThreadPool.SetMaxThreads(1500, 1500);

image.png

嗯嗯,相比底噪,差距还是蛮大的,因此尽可以使用。

5. 小结

8月更新完毕,其实还是蛮困难的,写到最后都不知道写啥了,生成速度完全跟不上啊。

例行小结,理性看待!

结的是啥啊,结的是我想你点赞而不可得的寂寞。😳😳😳

👓都看到这了,还在乎点个赞吗?

👓都点赞了,还在乎一个收藏吗?

👓都收藏了,还在乎一个评论吗?