翻译者 | 陈勇
白眉林 | 屠敏
没人的地方性就有武林,有武林的地方性就有争斗。提出诉讼编程词汇热门话题,协进会没人想回敬地争辩几番。这不,就在一名名叫@withinboredom的开发人员正式发布的两条“我最喜欢的词汇已由C#更改成PHP”的回帖上面,就没人则表示了置之不理。
@withinboredom在回帖中是这种叙述的:“当你对PHP和C#这三种词汇展开前述的基准测试时,会在许多示例中辨认出PHP的操控性强于C#。”
而用户@No McNoington却反驳道:“你有胆量就展现标识符示例,这种我就能断定为何你是错的。”
@withinboredom回怼到:“那个人(@No McNoington)连个松讷的本名都用不着起,那就准备好被firearms吧!”
PHP和C#在加载文档各方面的对决
@withinboredom具体来说展现的,是他指出“对五种词汇都十分公正”的加载文档标识符:PHP和C#将并行、稿子汉德瓦萨加载两个4Mib大小不一的文档。让他们看一看PHP和C#在加载文档各方面的对决吧!
PHP :
function test(){ $file = fopen(“/file/file.bin”, r); $counter = 0; $timer = microtime(true); while ( ! feof($file)) { $buffer = fgets($file, 4096); $counter += substr_count($buffer, 1); } $timer = microtime(true) – $timer; fclose($file); printf(“counted %s 1s in %s milliseconds\n”, number_format($counter), number_format($timer * 1000, 4));} test();C#:
using System.Diagnostics;using System.Text;var test = () => { using var file = File.OpenText(“/file/file.bin”); var counter = 0; var sw = Stopwatch.StartNew(); while(!file.EndOfStream) { if(file.Read() == 1) { counter++; } } sw.Stop(); Console.WriteLine($”Counted {counter:N0} 1s in {sw.Elapsed.TotalMilliseconds:N4} milliseconds”);}; test();“加载文档几乎不包含使用者级标识符,只是单纯测试一种词汇的基本功能。”@withinboredom还补充道,标识符中添加计数只是为了防止PHP或C#中的编译器擅自优化或删除标识符,并无其他作用。
然而,有些开发人员对那个测试反驳道:“PHP并没有两个字节两个字汉德瓦萨加载文档啊(PHP中的fgets()函数用于从文档中加载一行)!”@withinboredom火速回怼:“可C#也不是逐个字节加载的!理论上加载方式是一样的。”
以下是三种词汇在加载4Mib文档下的对比结果:
PHP:32.49毫秒(平均超过10次运行)
C#:37.30毫秒(平均超过10次运行)
4Mib大概只是一张完整照片的大小不一,所以为了进一步断定PHP的优越,@withinboredom还测试了这三种词汇加载2.5g视频大小不一的文档速率:
PHP:24.82秒(平均超过10次运行)
C#:26.67秒(平均超过10次运行)
综上能得出,不论是4Mib还是2.5g文档,PHP在加载文档速率各方面都强于C#。
函数调用开销是“罪魁祸首”?
很多开发人员指出这是由于C#没有以二进制模式加载文档,其中函数调用开销是罪魁祸首。然而,@withinboredom则表示,在函数调用各方面, C#比PHP快很多个数量级,所以问题不在于此。以下是2.5gb文档中二进制模式的标识符:
using System.Diagnostics;using System.Text; var binTest = () =>{ using var file = File.OpenRead(“/file/file.bin”); var counter = 0; var buffer = new byte[4096]; var numRead = 0; var sw = Stopwatch.StartNew(); while ((numRead = file.Read(buffer, 0, buffer.Length)) != 0) { counter += buffer.Take(numRead).Count((x) => x == 1); } sw.Stop(); Console.WriteLine($”Counted {counter:N} 1s in {sw.Elapsed.TotalMilliseconds} milliseconds”);}; binTest();考虑到没人指出会是Linq(词汇集成查询)的问题,@withinboredom删除了.Take和重复计数的相关标识符:
有.Take:38.40s(2.5gb文档)
没有.Take:23.5s(2.5gb文档——错误的实现)
关于查看文档操控性的测试
因为许多开发人员想优化C#而不优化PHP,所以@withinboredom设计了上面只查看文档操控性的测试,供开发人员参考。
PHP:
function test(){ $file = fopen(“/file/file.bin”, r); $counter = 0; $timer = microtime(true); while (stream_get_line($file, 4096) !== false) { ++$counter; } $timer = microtime(true) – $timer; fclose($file); printf(“counted %s 1s in %s milliseconds\n”, number_format($counter), number_format($timer * 1000, 4));}test();C#:
var binTest = () =>{ using var file = File.OpenRead(“/file/file.bin”); var counter = 0; var buffer = new byte[4096]; var sw = Stopwatch.StartNew(); while (file.Read(buffer, 0, buffer.Length) != 0) { counter += 1; } sw.Stop(); Console.WriteLine($”Counted {counter:N} 1s in {sw.Elapsed.TotalMilliseconds} milliseconds”);}; binTest();经测试,结果如下:
PHP:423.50毫秒(平均超过10次运行)
C#:530.42毫秒(平均超过10次运行)
据@withinboredom介绍,PHP和C#之间的操控性差异是他在去年辨认出的。当时他正巧在将许多杂七杂八的文档转移至Dapr(分布式应用程序)和Kubernetes,结果无意中辨认出:在加载文档各方面,PHP居然比C#更快!
尽管@withinboredom则表示目前他最爱的编程词汇已变为PHP,但这并不代表C#开发人员就要为此放弃一切,用PHP(或更好的C)重写所有文档的编写内容:“几毫秒的差距是不会毁掉开发人员的。”
原文链接:https://withinboredom.info/blog/2022/03/16/yes-php-is-faster-than-c/
END
《新程序员001-004》全面上市,对话世界级大师,报道中国IT行业创新创造