C-Sharp | Java | Python | Swift | GO | WPF | Ruby | Scala | F# | JavaScript | SQL | PHP | Angular | HTML
Tip: The JIT compiler can also detect the sealed decoration and optimize method invocations better when it is used.
Next: We show an interface with one method (ITest) and 2 classes that implement that interface.
Here: The first class, TestA, is not sealed. The second class, TestB, has the sealed decoration.
C# program that uses sealed class
using System;
/// <summary>
/// Example interface.
/// </summary>
interface ITest
{
/// <summary>
/// Method required by the interface.
/// </summary>
int GetNumber();
}
/// <summary>
/// Non-sealed class that implements an interface.
/// </summary>
class TestA : ITest
{
/// <summary>
/// Interface implementation.
/// </summary>
public int GetNumber()
{
return 1;
}
}
/// <summary>
/// Sealed class that implements an interface.
/// </summary>
sealed class TestB : ITest
{
/// <summary>
/// Interface implementation.
/// </summary>
public int GetNumber()
{
return 2;
}
}
class Program
{
static void Main()
{
ITest test1 = new TestA(); // Regular class
ITest test2 = new TestB(); // Sealed instantiation
Console.WriteLine(test1.GetNumber()); // TestA.GetNumber
Console.WriteLine(test2.GetNumber()); // TestB.GetNumber
}
}
Output
1
2
C# program that causes sealed error
class Bird
{
}
sealed class Test : Bird
{
}
class Example : Test
{
}
class Program
{
static void Main()
{
}
}
Output
Error CS0509 'Example':
cannot derive from sealed type 'Test'
Version 1: This version of the code calls methods on a derived class that is not sealed. The GetNumber method is repeatedly called.
Version 2: Here we call a method on a derived class that has the sealed keyword. It performs the same actions as version 1.
Result: For interface-heavy programs, the sealed decoration can result in a speedup on all method calls with no downside.
C# program that benchmarks sealed, not-sealed classes
using System;
using System.Diagnostics;
interface ITest
{
int GetNumber();
}
class TestA : ITest
{
public int GetNumber()
{
return 1;
}
}
sealed class TestB : ITest
{
public int GetNumber()
{
return 2;
}
}
class Program
{
const int _max = 10000000;
static void Main()
{
int sum1 = 0;
int sum2 = 0;
ITest test1 = new TestA();
ITest test2 = new TestB();
var s1 = Stopwatch.StartNew();
// Version 1: use non-sealed class method calls.
for (int i = 0; i < _max; i++)
{
sum1 += test1.GetNumber();
sum1 += test1.GetNumber();
sum1 += test1.GetNumber();
sum1 += test1.GetNumber();
sum1 += test1.GetNumber();
}
s1.Stop();
var s2 = Stopwatch.StartNew();
// Version 2: use sealed class method calls.
for (int i = 0; i < _max; i++)
{
sum2 += test2.GetNumber();
sum2 += test2.GetNumber();
sum2 += test2.GetNumber();
sum2 += test2.GetNumber();
sum2 += test2.GetNumber();
}
s2.Stop();
Console.WriteLine(((double)(s1.Elapsed.TotalMilliseconds * 1000000) /
_max).ToString("0.00 ns"));
Console.WriteLine(((double)(s2.Elapsed.TotalMilliseconds * 1000000) /
_max).ToString("0.00 ns"));
}
}
Output
8.11 ns Not sealed class, GetNumber
7.75 ns Sealed class, GetNumber
Then: The runtime looks for the method location during execution. Each type has a Type pointer. This is used for virtual method dispatch.
TypeAlso: If you execute this program in the Visual Studio environment, the sealed optimization is not applied.
However: You can run the program outside of the debugger by clicking on the executable.