If you instead compute the filename within the class itself, it will run much faster, in exchange for decreased performance when modifying the object. Mind you, I'd be very concerned if computing a filename was a bottleneck; writing to the file is way slower than coming up with its name.
See code samples below. When I benchmarked them with optimizations on (in LINQPad 5), Test2 ran about 15x faster than Test1. Among other things, Test2 doesn't constantly generate/discard tiny string objects.
void Main()
{
Test1();
Test1();
Test1();
Test2();
Test2();
Test2();
}
void Test1()
{
System.Diagnostics.Stopwatch sw = new Stopwatch();
MyObject1 mo = new MyObject1 { Name = "MyName" };
sw.Start();
long x = 0;
for (int i = 0; i < 10000000; ++i)
{
x += CreateFileName(mo).Length;
}
Console.WriteLine(x); //Sanity Check, prevent clever compiler optimizations
sw.ElapsedMilliseconds.Dump("Test1");
}
public string CreateFileName(MyObject1 obj)
{
return "sometext-" + obj.Name + ".txt";
}
void Test2()
{
System.Diagnostics.Stopwatch sw = new Stopwatch();
MyObject2 mo = new MyObject2 { Name = "MyName" };
sw.Start();
long x = 0;
for (int i = 0; i < 10000000; ++i)
{
x += mo.FileName.Length;
}
Console.WriteLine(x); //Sanity Check, prevent clever compiler optimizations
sw.ElapsedMilliseconds.Dump("Test2");
}
public class MyObject1
{
public string Name;
}
public class MyObject2
{
public string FileName { get; private set;}
private string _name;
public string Name
{
get
{
return _name;
}
set
{
_name=value;
FileName = "sometext-" + _name + ".txt";
}
}
}
I also tested adding memoization to CreateFileName
, but it barely improved performance over Test1, and it couldn't possibly beat out Test2, since it performs the equivalent steps with additional overhead for hash lookups.