C#版本的CPU性能测试

本文涉及的产品
性能测试 PTS,5000VUM额度
简介:

本文不讲C#开发技巧,只测试同样的代码在不同CPU的机器上的运行速度。结果包括普通版本和并行版本的对比,方便大家选配电脑,对“性能”有个感性的认识。

一. 测试原理

    字符串相关度计算是文本处理和数据挖掘中一个不可或缺的方法,例如论文查重等。Levenshtein Distance可以用来比较两个字符串的相似度,即两个字符串之间的“距离”。这个“距离”其实就是从源字符串变换到目标字符串需要进行的删除、插入和替换的次数。算法简图如下:

  字符串相似度比较Levenshtein <wbr>Distance

   有不少该算法的改进版本,可大幅度提升效率,不过这不是本文的目的。我们的目的就是看看该算法在不同的机器下到底能跑多快,再看并行优化后又能跑多快。该算法基本只对CPU性能敏感,很适合做测试。

   我们随机生成1000个1000长度的字符串,并比较字符串相关度。示例工程可在文末找到,由于需要并行计算,需要VS2010,.NET4.0支持。

  代码如下:

View Code
namespace SpeedTest
{
    using System;
    using System.Diagnostics;
    using System.Text;
    using System.Threading.Tasks;

    internal class Program
    {
        #region Methods

        private static void Main(string[] args)
        {
            var  watch =new Stopwatch();
            const long count = 1000;
            const int length = 1000;
            string comparestring = StringDistance.GenerateRandomString(length);
            var strlist = new string[count];
            var steps = new int[count];
            // prepare string[] for comparison  

            Parallel.For(0, count, i => strlist[i] = StringDistance.GenerateRandomString(length));

            Console.WriteLine("已经生成了" + count + "个长度为" + length + "的字符串");

            watch.Start();
            for (int i = 0; i < count; i++)
            {
                steps[i] = StringDistance.LevenshteinDistance(comparestring, strlist[i]);
            }
            watch.Stop();
            Console.WriteLine("完成非并行计算,耗时(ms)"+watch.ElapsedMilliseconds);
            Console.WriteLine("性能比" + 100000d/watch.ElapsedMilliseconds);
            watch.Reset();
            watch.Start();
            Parallel.For(
                0, count, delegate(long i) { steps[i] = StringDistance.LevenshteinDistance(comparestring, strlist[i]); });
            watch.Stop();
            Console.WriteLine("完成并行计算,耗时(ms)" + watch.ElapsedMilliseconds);
            Console.WriteLine("性能比" + 100000d / watch.ElapsedMilliseconds);
             Console.ReadKey();
        }

        #endregion
    }

    internal class StringDistance
    {
        #region Public Methods

        public static string GenerateRandomString(int length)
        {
            var r = new Random((int)DateTime.Now.Ticks);
            var sb = new StringBuilder(length);
            for (int i = 0; i < length; i++)
            {
                int c = r.Next(97, 123);
                sb.Append(Char.ConvertFromUtf32(c));
            }
            return sb.ToString();
        }

        public static int LevenshteinDistance(string str1, string str2)
        {
            var scratchDistanceMatrix = new int[str1.Length + 1,str2.Length + 1];
            // distance matrix contains one extra row and column for the seed values         
            for (int i = 0; i <= str1.Length; i++)
            {
                scratchDistanceMatrix[i, 0] = i;
            }
            for (int j = 0; j <= str2.Length; j++)
            {
                scratchDistanceMatrix[0, j] = j;
            }
            for (int i = 1; i <= str1.Length; i++)
            {
                int str1Index = i - 1;
                for (int j = 1; j <= str2.Length; j++)
                {
                    int str2Index = j - 1;
                    int cost = (str1[str1Index] == str2[str2Index]) ? 0 : 1;
                    int deletion = (i == 0) ? 1 : scratchDistanceMatrix[i - 1, j] + 1;
                    int insertion = (j == 0) ? 1 : scratchDistanceMatrix[i, j - 1] + 1;
                    int substitution = (i == 0 || j == 0) ? cost : scratchDistanceMatrix[i - 1, j - 1] + cost;
                    scratchDistanceMatrix[i, j] = Math.Min(Math.Min(deletion, insertion), substitution);
                    // Check for Transposition  
                    if (i > 1 && j > 1 && (str1[str1Index] == str2[str2Index - 1]) &&
                        (str1[str1Index - 1] == str2[str2Index]))
                    {
                        scratchDistanceMatrix[i, j] = Math.Min(
                            scratchDistanceMatrix[i, j], scratchDistanceMatrix[i - 2, j - 2] + cost);
                    }
                }
            }
            // Levenshtein distance is the bottom right element       
            return scratchDistanceMatrix[str1.Length, str2.Length];
        }

        #endregion
    }
}

 

  废话不说,上测试结果。

 

   二.测试结果

     1. Debug,Debug直接运行,Release调试,Release直接运行的区别

      以上四种环境对应不同开发阶段的软件性能,对开发的性能调优有指导价值。

      电脑配置如下:

image

测试结果如下,数值为执行时间,单位为ms

image

image

    值得注意的是,在不同代码下四种环境的结果是很不相同的。一般情况下软件直接运行要比调试快很多。Release模式比Debug模式快几倍。但在这个示例下,直接运行和调试却没有特别明显的区别,希望大神能给予解答。

   另外,并行算法比普通的串行算法快了四倍。符合四核CPU的实际情况。

      2.不同CPU下的性能

   接下来,我们来看不同CPU下的性能区别。为简化测试,以下所有结果都采用Release运行模式。对比不同CPU在串行/并行下的速度区别。

  结果都是以执行时间ms表示的,值越小越好。

 

古老电脑AMD QL-62 双核心 2.00GHz

image

难得找到AMD的笔记本电脑,该CPU已经停产很久了,三年前的CPU不负众望,成绩还不错,当然并行成绩比服务器慢了十几倍。

笔记本T8100,双核2.4G

image

I3 2310 笔记本核心,双核,2.1GHz

image

   虽然比T8100的频率低,但新一代酷睿I3还是完虐T8100的。

桌面老牌酷睿E7300 双核心2.67GHz

image

回想06年底,能买到酷睿E6300是刚上高三的我最大的梦想,现在看来是在不敢恭维,并行速度和I7比差了四倍不止。这款当时很牛的桌面CPU连现在低端的笔记本CPU都不如。

 

华硕笔记本UX31A, I5 3317U   双核双线程, @2.3GHz Auto OC

      image

  超级本的性能还是不错的,也体现出了双核的优势。在“节能模式”下,CPU不会自动睿频,只有1.7GHz。结果惨不忍睹。超级本一般情况下做开发足够了。

第二代酷睿笔记本I5 2430 @ 2.3GHz

 

 

image

不得不说,标压笔记本的I5都可以完虐超低压的I7.  谁让超级本必须做到那么薄呢? 价格还死贵。如果考虑性能和性价比,还是选标压CPU吧。

联想台式机 I3 2130 @3.4GHz

image

虽然是I3,但在串行下与同频的I7几乎无区别,当然由于是双核的,并行速度正好是串行的一半。

I7 2600 四核八线程  3.4GHz

      image

实在没有找到2600K的超频结果,就先用2600默频凑数吧,单核性能中规中矩。

I5 2500K OC 4.2GHz 四核四线程

image

寝室台式机的跑分,看来频率是王道啊,在4.2G轻松秒杀I7 2600。

      服务器核心X5670  六核心 @2.93Ghz

 image

服务器六核心CPU看似高端,但在这个程序下,还是无法与2600甚至2130抗衡,并行加速比4.66, 六核心有点小吃亏。

        服务器核心E5 2690 8核心,双CPU共16核心, 2.9GHz *2

image 

  这几乎是我目前看到的最好结果, 该CPU在串行模式下就达到了11.657s的水平,并行加速比达到了可喜的7.32。可是与2500K这样的CPU不对等的是它的售价,一万三四够买10个2500K了。

 

3. 测试总结和对比

  下图是不同CPU串行速度的对比图:

image

   我们看到基本上同平台,同架构的CPU间,频率是王道。而当前I3新酷睿都可以干掉当年桌面的老酷睿经典,不得不说技术发展迅速。而服务器核心虽然核心多,甚至是双CPU,但频率一般,因此在这种普通应用下甚至抗不过桌面的I5 2500K。 能多核优化的程序还是占少数,大家能超就超一点吧,超频带来的性能提升真心不是一点点。

下图是并行下速度对比图:

image

并行计算下,核的数量是王道!在非服务器核心上,加速比几乎就是CPU核心数。四核的速度就是比双核的快。在八核的顶级服务器CPU上,它的速度几乎是AMD QL-62的13倍!但若算是这台机器有双CPU16个核心的话,加速比和16还是差很多的。难道.NET并行库对多CPU支持不好?我怎么记得它可以支持最多64个CPU?

 

三. 总结和源代码下载

       咱不是专业的硬件测评师,只是好奇之下跑了几个分数看了他们的性能而已,花了整整一晚上时间,因此若有不足之处还请海涵。

       总体来说,单核性能频率和架构决定一切,多核性能上核心数决定了加速比。 桌面级应用完全没必要买服务器的多核心(E3 1230这类除外)。大部分程序最多只对四核CPU做过优化。更多核心甚至双CPU会造成各种不兼容性问题,连游戏都打不了(嘿嘿),编程都卡。

       现在觉得,I5 2500K还是要比E3 1230性价比高很多,超频超出来的性能不是盖的。别担心寿命,它只会在需要的时候睿频到更高的频率,平时都是乖乖的二点几吉赫兹。而且非常简单!Enjoy it!

       程序并行的优势还是非常明显的,.NET的并行库可比Intel并行库方便多了(虽然效率不能比),但它可以很好的帮助你挖掘多核CPU的潜力。大家可以多学习一下.NET并行库。

       源代码下载


作者:热情的沙漠
出处:http://www.cnblogs.com/buptzym/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

标签: .NET, 性能测试

本文转自FerventDesert博客园博客,原文链接:http://www.cnblogs.com/buptzym/archive/2012/11/24/2785408.html,如需转载请自行联系原作者
相关实践学习
通过性能测试PTS对云服务器ECS进行规格选择与性能压测
本文为您介绍如何利用性能测试PTS对云服务器ECS进行规格选择与性能压测。
目录
相关文章
|
1月前
|
运维 Prometheus 监控
如何在测试环境中保持操作系统、浏览器版本和服务器配置的稳定性和一致性?
如何在测试环境中保持操作系统、浏览器版本和服务器配置的稳定性和一致性?
|
1月前
|
安全 Linux 虚拟化
|
2月前
|
测试技术 C# 数据库
C# 单元测试框架 NUnit 一分钟浅谈
【10月更文挑战第17天】单元测试是软件开发中重要的质量保证手段,NUnit 是一个广泛使用的 .NET 单元测试框架。本文从基础到进阶介绍了 NUnit 的使用方法,包括安装、基本用法、参数化测试、异步测试等,并探讨了常见问题和易错点,旨在帮助开发者有效利用单元测试提高代码质量和开发效率。
167 64
|
14天前
|
算法 Java 测试技术
Benchmark.NET:让 C# 测试程序性能变得既酷又简单
Benchmark.NET是一款专为 .NET 平台设计的性能基准测试框架,它可以帮助你测量代码的执行时间、内存使用情况等性能指标。它就像是你代码的 "健身教练",帮助你找到瓶颈,优化性能,让你的应用跑得更快、更稳!希望这个小教程能让你在追求高性能的路上越走越远,享受编程带来的无限乐趣!
61 13
|
4月前
|
测试技术 API C#
C#使用Bogus生成测试数据
C#使用Bogus生成测试数据
59 1
|
1月前
|
缓存 监控 数据挖掘
C# 一分钟浅谈:性能测试与压力测试
【10月更文挑战第20天】本文介绍了性能测试和压力测试的基础概念、目的、方法及常见问题与解决策略。性能测试关注系统在正常条件下的响应时间和资源利用率,而压力测试则在超出正常条件的情况下测试系统的极限和潜在瓶颈。文章通过具体的C#代码示例,详细探讨了忽视预热阶段、不合理测试数据和缺乏详细监控等常见问题及其解决方案,并提供了如何避免这些问题的建议。
56 7
|
1月前
|
Kubernetes 测试技术 持续交付
C# 一分钟浅谈:集成测试与系统测试
【10月更文挑战第19天】本文详细介绍了集成测试和系统测试的概念、目的及其在软件开发中的重要性。通过分析常见问题和易错点,结合代码示例,探讨了如何通过代码规范、自动化测试和持续集成等方法提高测试效果,确保软件质量和可靠性。
91 1
|
2月前
|
测试技术 C# 数据库
C# 一分钟浅谈:测试驱动开发 (TDD) 实践
【10月更文挑战第18天】测试驱动开发(TDD)是一种软件开发方法论,强调先编写测试代码再编写功能代码,以确保代码质量和可维护性。本文从 TDD 的基本概念入手,详细介绍了其核心步骤——编写测试、运行测试并失败、编写代码使测试通过,以及“红绿重构”循环。文章还探讨了 TDD 的优势,包括提高代码质量、促进设计思考、减少调试时间和文档化。此外,文中分析了常见问题及解决方案,如测试覆盖率不足、测试代码过于复杂、忽视重构和测试依赖过多,并通过一个简单的计算器类的代码案例,展示了 TDD 的实际应用过程。
45 1
|
2月前
|
机器学习/深度学习 弹性计算 自然语言处理
前端大模型应用笔记(二):最新llama3.2小参数版本1B的古董机测试 - 支持128K上下文,表现优异,和移动端更配
llama3.1支持128K上下文,6万字+输入,适用于多种场景。模型能力超出预期,但处理中文时需加中英翻译。测试显示,其英文支持较好,中文则需改进。llama3.2 1B参数量小,适合移动端和资源受限环境,可在阿里云2vCPU和4G ECS上运行。
126 1
|
2月前
|
机器学习/深度学习 算法 PyTorch
目标检测实战(五): 使用YOLOv5-7.0版本对图像进行目标检测完整版(从自定义数据集到测试验证的完整流程)
本文详细介绍了使用YOLOv5-7.0版本进行目标检测的完整流程,包括算法介绍、环境搭建、数据集准备、模型训练、验证、测试以及评价指标。YOLOv5以其高精度、快速度和模型小尺寸在计算机视觉领域受到广泛应用。
944 0
目标检测实战(五): 使用YOLOv5-7.0版本对图像进行目标检测完整版(从自定义数据集到测试验证的完整流程)
下一篇
DataWorks