C#与Java统计大文件中指定值字节数量的性能差异问询:为何C#慢5倍?
C#与Java统计大文件中指定值字节数量的性能差异问询:为何C#慢5倍?
最近我做了个C#和Java的性能对比测试,结果发现了一个让我困惑的情况——统计1亿字节的随机二进制文件中值大于100的字节数量时,C#的速度居然比Java慢了差不多5倍!我已经排除了调试模式的影响,甚至用BenchmarkDotNet做了严谨测试,结果还是差不多,想请教各位大佬这是怎么回事,有没有优化的方向?
测试准备:生成测试文件
首先我用Python生成了一个100,000,000字节的随机二进制文件,代码如下:
import random import os def Main(): length = 100000000 randomArray = random.randbytes(length) desktopPath = os.path.normpath(os.path.expanduser("~/Desktop")) fullPath = os.path.join(desktopPath, "RandomFile.dat") if os.path.isfile(fullPath): print("File already exists.") return with open(fullPath, "wb") as file: file.write(randomArray) print("The file has been created.") Main()
核心测试逻辑
接下来我分别用C#和Java实现了统计逻辑,只统计TestSpeed核心函数的执行时间(文件读取和类型转换的时间不算在性能测试范围内)。
C# 实现代码
using System; using System.Diagnostics; using System.IO; namespace TestYouTube { public class Program { public static void Main(string[] args) { string desktopPath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop); string fullPath = Path.Combine(desktopPath, "RandomFile.dat"); if (!File.Exists(fullPath)) { Console.WriteLine("The file does not exist."); return; } byte[] byteArray = File.ReadAllBytes(fullPath); int[] intArray = ByteArrayToIntArray(byteArray); Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); int count = TestSpeed(intArray); stopwatch.Stop(); Console.WriteLine($"Count = {count}"); Console.WriteLine($"Elapsed: {stopwatch.Elapsed.TotalSeconds} seconds"); Console.ReadLine(); } private static int[] ByteArrayToIntArray(byte[] byteArray) { if (byteArray == null) return null; if (byteArray.Length == 0) return Array.Empty<int>(); int[] intArray = new int[byteArray.Length]; for (int i = 0; i < intArray.Length; i++) { intArray[i] = byteArray[i]; } return intArray; } private static int TestSpeed(int[] array) { if (array == null) throw new ArgumentNullException(); if (array.Length == 0) throw new ArgumentException(); int count = 0; foreach (int element in array) { if (element > 100) { count++; } } return count; } } }
Java 实现代码
import java.io.*; import java.nio.file.*; import javax.swing.filechooser.FileSystemView; public class Main { public static void main(String[] args) throws IOException { FileSystemView view = FileSystemView.getFileSystemView(); File file = view.getHomeDirectory(); String desktopPath = file.getPath(); Path fullPath = Paths.get(desktopPath, "RandomFile.dat"); File randomFile = new File(fullPath.toString()); if (!randomFile.exists() || randomFile.isDirectory()) { System.out.println("The file does not exist."); return; } byte[] array = Files.readAllBytes(randomFile.toPath()); int[] intArray = ByteArrayToUnsignedByteArray(array); long start = System.currentTimeMillis(); int count = TestSpeed(intArray); long end = System.currentTimeMillis(); long elapsed = end - start; double elapsedSeconds = ((double) elapsed) / 1000; System.out.printf("Count = %d\n", count); System.out.printf("Elapsed: %f seconds\n", elapsedSeconds); } private static int ByteToUnsignedByte(byte b) { return b & 0b11111111; } private static int[] ByteArrayToUnsignedByteArray(byte[] byteArray) { if (byteArray == null) return null; if (byteArray.length == 0) return new int[0]; int[] newArray = new int[byteArray.length]; for (int i = 0; i < byteArray.length; i++) { int element = ByteToUnsignedByte(byteArray[i]); newArray[i] = element; } return newArray; } private static int TestSpeed(int[] byteArray) { if (byteArray == null) throw new IllegalArgumentException("The array must not be null."); if (byteArray.length == 0) throw new IllegalArgumentException("The array length must be non zero."); int count = 0; for (int element : byteArray) { if (element > 100) { count++; } } return count; } }
测试环境参数
- .NET版本:.NET 9.0
- Java版本:OpenJDK 24.0.1 2025-04-15
- 操作系统:Windows 10 专业版 [Version 10.0.19045.5965]
- CPU:AMD Athlon Gold 3150U with Radeon Graphics(双核Zen 1架构)
测试结果
我多次运行测试,结果非常稳定:
- C#:用
Stopwatch测试耗时约0.428秒,用BenchmarkDotNet测试的Mean值为411.2ms - Java:耗时约0.077秒
两者的统计结果一致(都是60542647),但C#的速度只有Java的1/5左右。我已经确认是用Release模式+Start Without Debugging启动的C#程序,排除了调试开销的影响。
我的疑问
- 为什么两者的性能差异会这么大?是我的C#代码有可以优化的点,还是JIT编译器(RyuJIT vs HotSpot)的优化策略差异导致的?
- 有没有什么优化手段能让C#的性能追上Java?
内容来源于stack exchange
相关产品推荐
相关产品推荐

