admin管理员组文章数量:1122879
I need to test how different ways of string formatting affect the performance. And I found a surprising result. Let me explain with two test cases:
// Test Case 2
for (int i = 0; i < 10000000; i++)
{
var message = string.Format("Test Message{0}{1}{2}{3}{4}", int1, int2, int3, int4, int5);
}
// Test Case 3
for (int i = 0; i < 10000000; i++)
{
var message = string.Format("Test Message{0}{1}{2}{3}{4}", new object[] { int1, int2, int3, int4, int5 });
}
Output
Test Case 2 - Elapsed Time: 1770 ms
Test Case 2 - Memory Used: 28528 bytes
Test Case 3 - Elapsed Time: 1685 ms
Test Case 3 - Memory Used: 360 bytes
The Question
As you can see, memory usage is ~100 times more in Test Case 2 (where string.Format
uses arguments directly) compared to Test Case 3 (where arguments are wrapped in an object[]
explicitly).
But why?
As I understand, string.Format
should implicitly convert arguments into an object[]
anyway. What is happening here that causes such a drastic difference in memory usage?
I am expecting to see nearly equal memory usage.
Notes
int1 = 1
,int2 = 2
...- to track time I use stopWatch
- to track memory I use
beforeMemory = GC.GetTotalMemory(true);
and compare the values before and after the execution
Full code that I use for "benchmarking":
using System.Diagnostics;
internal class Program
{
private static void Main(string[] args)
{
//var fileStream = new FileStream(
//"C:\\Users\\osavytskyy\\Documents\\Projects\\TestScript\\file.txt",
//FileMode.OpenOrCreate,
//FileAccess.ReadWrite,
//FileShare.None); // Prevents other processes from reading or writing
//Console.Read();
//fileStream.Dispose();
var int1 = 1;
var int2 = 2;
var int3 = 3;
var int4 = 4;
var int5 = 5;
var filestream = new LogStreamFile("C:\\Projects\\TestProj\\file.txt");
Stopwatch stopwatch = new Stopwatch();
// Test Case 1
long beforeMemory = GC.GetTotalMemory(true);
stopwatch.Start();
for (int i = 0; i < 10000000; i++)
{
var message = string.Format("Test Message");
}
stopwatch.Stop();
Console.WriteLine($"Test Case 1 - Elapsed Time: {stopwatch.ElapsedMilliseconds} ms");
Console.WriteLine($"Test Case 1 - Memory Used: {GC.GetTotalMemory(true) - beforeMemory} bytes");
// Test Case 2
beforeMemory = GC.GetTotalMemory(true);
stopwatch.Reset();
stopwatch.Start();
for (int i = 0; i < 10000000; i++)
{
var message = string.Format("Test Message{0}{1}{2}{3}{4}", int1, int2, int3, int4, int5);
}
stopwatch.Stop();
Console.WriteLine($"Test Case 2 - Elapsed Time: {stopwatch.ElapsedMilliseconds} ms");
Console.WriteLine($"Test Case 2 - Memory Used: {GC.GetTotalMemory(true) - beforeMemory} bytes");
// Test Case 3
beforeMemory = GC.GetTotalMemory(true);
stopwatch.Reset();
stopwatch.Start();
for (int i = 0; i < 10000000; i++)
{
//var arg = new object[] { var1, var2, var3, var4, var5 };
var message = string.Format("Test Message{0}{1}{2}{3}{4}", new object[] { int1, int2, int3, int4, int5 });
}
stopwatch.Stop();
Console.WriteLine($"Test Case 3 - Elapsed Time: {stopwatch.ElapsedMilliseconds} ms");
Console.WriteLine($"Test Case 3 - Memory Used: {GC.GetTotalMemory(true) - beforeMemory} bytes");
// Test Case 4
beforeMemory = GC.GetTotalMemory(true);
stopwatch.Reset();
stopwatch.Start();
for (int i = 0; i < 10000000; i++)
{
var message = $"Test Message{int1}{int2}{int3}{int4}{int5}";
}
stopwatch.Stop();
Console.WriteLine($"Test Case 4 - Elapsed Time: {stopwatch.ElapsedMilliseconds} ms");
Console.WriteLine($"Test Case 4 - Memory Used: {GC.GetTotalMemory(true) - beforeMemory} bytes");
}
}
本文标签:
版权声明:本文标题:c# - Why does String.Format("text{0}", x1, x2, x3) take way more memory than String.Format("text {0}& 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1736196605a1910492.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论