// 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 });
}
Вывод
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
Вопрос
Как видите, использование памяти примерно в 100 раз больше в тестовом примере 2 (где строка .Format использует аргументы напрямую) по сравнению с тестовым примером 3 (где аргументы явно заключаются в объект[]).
Но почему?
Насколько я понимаю, string.Format должен в любом случае неявно преобразуйте аргументы в объект[]. Что здесь происходит, что вызывает такую резкую разницу в использовании памяти?
Я ожидаю увидеть почти равное использование памяти.
Примечания
- int1 = 1, int2 = 2 ...
- для отслеживания времени я использую StopWatch
- для отслеживания памяти, которую я использую beforeMemory = GC.GetTotalMemory(true); и сравниваем значения до и после выполнения
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");
}
}
Подробнее здесь: https://stackoverflow.com/questions/792 ... n-string-f