by Conmajia
破除现代迷信, 人人有责.
被警告了, 无码变有码.
赞助过本文的大佬
奇了个怪
.NET 作为开发平台来说, 不可否认是优雅的, 高效的. 可是有些人就是看不到它极高的开发效率, 极短的市场推出时间, 极强的扩展能力, 非得在性能上较劲, 把一帮小萌新忽悠得一说起 .NET 就觉着是 "慢","卡" 的代名词.
这些人总是存在一个思维误区, 认为程序性能是和语言挂钩的. 您没事儿吧? 真要这样,《数据结构》,《算法》这些课早他妈该撤了好吧. 汽车和飞机速度确实不一样, 但就算给您一架私人飞机, 您能给表演表演每天开飞机去买菜? 任何语言的性能瓶颈, 大半还是出在使用这语言的人蠢身上. 新手司机开着十辆布加迪也不可能拼过驰骋秋名山的五菱宏光老司机. 咱们不抬杠, 今天就只说性能, 不说开发效率, 上市速度. 非要跟我抬杠, 算上这些, 可能我的 "低性能" 产品已经出街了, 你憋半天憋不出屁的 "高性能" 产品快扑街了, 优越个8 呢.
.NET 的开发语言一般用 C#, 后边我就不区分 .NET 和 C# 了. F# 其实也差不多, 反正最后都编译成 intermediate language, 可以认为是等价的 (函数式编程更多的是一种思想, 这个话题我以后会写). 实话实说, C# 这门编程语言, 一开始就处于一个挺尴尬的位置. 性能上, 有 C/C++ 在前边拦着; 应用上, 有 Java,Python 在后边堵截, 不上不下..NET 玩家心里总憋着股邪火, 只好左右互搏, 自娱自乐了.
语言的比较
这个问题的根源, 很大一部分在于很多程序员只会一种语言, 甚至连这唯一的语言也不够精通, 所以才会要么看不起别的语言, 要么埋怨自己这语言性能太弱. 想要一招鲜吃遍天, 梦里可以, 醒来最好还是把这茬给忘了. 而那些对 .NET 一知半解就开始嘲讽的 "别的语言" 玩家, 就更别指望他们能理解到其中的精髓了.
把自己限制于一种语言的程序员会经常错过其他地方提供的重要机会. 这样的程序员绝对不会被他们的老板或客户看成是专业领域中的专家.
- --Oliver Sturm
- C# 虽然定位尴尬, 但是它本身是高度优化的, 要比性能, 无非就 C/C++ 或者汇编才配跟它比. Java,Python 这些, 大家都是 IL 解释的, 本是同根生, 相煎急锤子, 都不一定能比过 C#.C 系玩家就算了, 特性使然确实比不过, 但是事实上优化之后性能也大差不差 (我马上就能证明这一点). 最奇怪的就是好多 J,P 玩家居然好意思笑话 C# 性能辣鸡, 完全没意识到自己那惨样儿. 就好像宋小宝去够姚明手里的球, 结果潘长江在边儿上笑得挺欢, 笑您 呢? 和机器码比起来, 任何使用中间语言虚拟机 / runtime 的语言都有损失, 这话没人能反驳吧? Benchmark, 一般都是用最耗资源的操作 -- 比如图像处理 -- 来比较. 这无非就是测试磁盘, 内存的 IO 性能呗. 操作系统最终的性能在那卡着, assembly 可以达到 95%,C 系 8,90%,C# 可能亏点儿, 6,70% 的样子. 然而, 这都不是重点, 重点在于, 你有没有完全利用到语言的全部特性, 以及那些你认为低效率的算法, 非要用它们真的大丈夫? 40 米大刀拿来削苹果, 可能它的性能真的很低吧.
我过去的试验
2012 年的时候我就测试过用 C# GDI + 读写 bitmap, 一开始用的常规算法, 很慢. 但是经过优化后, 性能提升了 363 倍, 我也没用别的任何类库, 还是 .NET 2.0 原生. 您说怎么判断 C# 的性能到底是低还是高?
▲ 2012 年的测试, 主要内容已经丢失, 我在网上找到的爬虫文章
当时一帮哥们儿看了我的试验都手痒秀了一遍优化:
- private void invert(Bitmap bmp) {
- Color sc = new Color();
- // 逐像素处理
- for (int i = 0; i <bmp.Width; i++) {
- for (int j = 0; j < bmp.Height; j++) {
- sc = bmp.GetPixel(i, j);
- bmp.SetPixel(i, j, Color.FromArgb(0xff - sc.R, 0xff - sc.G, 0xff - sc.B));
- }
- }
- }
- private void invert(Bitmap bmp) {
- BitmapData bdata = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, bmp.PixelFormat);
- Parallel.ForEach(Partitioner.Create(0, bdata.Height), (H) => {
- unsafe {
- int x, y, w, h, s;
- byte * s0, p;
- w = bdata.Width;
- h = bdata.Height;
- s = bdata.Stride;
- s0 = (byte * ) bdata.Scan0;
- // 逐像素处理
- for (y = H.Item1; y < H.Item2; y++) {
- p = s0 + y * s;
- for (x = 0; x < w; x++) {
- * p = (byte)(0xff - * p);
- p++;* p = (byte)(0xff - * p);
- p++;* p = (byte)(0xff - * p);
- p++;
- }
- }
- }
- });
- bmp.UnlockBits(bdata);
- }
来源: https://www.cnblogs.com/conmajia/p/low-performance-csharp-all-your-fault.html