Date: 23.03.2017 3:21:45
Visual Studio 2012, оптимизация включена: вычисляется 2 раза
private void Form1_Paint(object sender, PaintEventArgs e)
{
e.Graphics.DrawLine(Pens.Black, 0, this.captionTextHeight + this.captionLineWidth / 2, this.Width, this.captionTextHeight + this.captionLineWidth / 2);
}
// Code size 67 (0x43)
.maxstack 8
IL_0000: ldarg.2
IL_0001: callvirt instance class [System.Drawing]System.Drawing.Graphics [System.Windows.Forms]System.Windows.Forms.PaintEventArgs::get_Graphics()
IL_0006: call class [System.Drawing]System.Drawing.Pen [System.Drawing]System.Drawing.Pens::get_Black()
IL_000b: ldc.r4 0.0
IL_0010: ldarg.0
IL_0011: ldfld float32 WindowsFormsApplication1.Form1::captionTextHeight
IL_0016: ldarg.0
IL_0017: ldfld float32 WindowsFormsApplication1.Form1::captionLineWidth
IL_001c: ldc.r4 2.
IL_0021: div
IL_0022: add
IL_0023: ldarg.0
IL_0024: call instance int32 [System.Windows.Forms]System.Windows.Forms.Control::get_Width()
IL_0029: conv.r4
IL_002a: ldarg.0
IL_002b: ldfld float32 WindowsFormsApplication1.Form1::captionTextHeight
IL_0030: ldarg.0
IL_0031: ldfld float32 WindowsFormsApplication1.Form1::captionLineWidth
IL_0036: ldc.r4 2.
IL_003b: div
IL_003c: add
IL_003d: callvirt instance void [System.Drawing]System.Drawing.Graphics::DrawLine(class [System.Drawing]System.Drawing.Pen,
float32,
float32,
float32,
float32)
Поправка: вывод неверный, так как JIT дополнительно оптимизирует при выполнении, значение вычисляется один раз (см. ниже)Date: 23.03.2017 14:37:19
А, ну да. Я забыл, что в CLR JIT занимается оптимизацией. Действительно, введение промежуточной переменной не дает выигрыша.
Тем не менее, использование умножения вместо степени, по моим измерениям, дает существенный выигрыш
class Program
{
const int N = 10000000;
static Random r=new Random();
static double Magic(double x, double y)
{
return 5.1 * r.NextDouble() * x + 6.6 * r.NextDouble() * y;
}
static void Main(string[] args)
{
Stopwatch s;
Random rnd;
int i,k,m;
double x, y,z,t;
s = new Stopwatch();
rnd = new Random();
Console.WriteLine("Вычисление степени с помощью Math.Pow...");
s.Start();
for (i = 0; i < N; i++)
{
x = rnd.NextDouble() * 10.0;
y = Math.Pow(x, 2);
if (y == 100.0) Console.WriteLine("Bingo!");
}
s.Stop();
Console.WriteLine("t=" + s.ElapsedMilliseconds.ToString());
s = new Stopwatch();
rnd = new Random();
Console.WriteLine("Вычисление степени с помощью умножения...");
s.Start();
for (i = 0; i < N; i++)
{
x = rnd.NextDouble() * 10.0;
y = x * x;
if (y == 100.0) Console.WriteLine("Bingo!");
}
s.Stop();
Console.WriteLine("t=" + s.ElapsedMilliseconds.ToString());
/* ------------------------------------------------------------------*/
s = new Stopwatch();
rnd = new Random();
Console.WriteLine("Вычисление частного делением...");
s.Start();
for (i = 0; i < N; i++)
{
k = rnd.Next();
m = k / 2;
if (m == 12345) Console.WriteLine("JackPot!");
}
s.Stop();
Console.WriteLine("t=" + s.ElapsedMilliseconds.ToString());
s = new Stopwatch();
rnd = new Random();
Console.WriteLine("Вычисление частного сдвигом...");
s.Start();
for (i = 0; i < N; i++)
{
k = rnd.Next();
m = k >> 1;
if (m == 12345) Console.WriteLine("JackPot!");
}
s.Stop();
Console.WriteLine("t=" + s.ElapsedMilliseconds.ToString());
/* ------------------------------------------------------------------*/
s = new Stopwatch();
rnd = new Random();
Console.WriteLine("Расчет без промежуточной переменной...");
s.Start();
for (i = 0; i < N; i++)
{
x = rnd.NextDouble() * 10.0;
y = rnd.NextDouble() * 5.0;
z = Magic(x + y, x + y);
if (z == 1111.11) Console.WriteLine("Magic!");
}
s.Stop();
Console.WriteLine("t=" + s.ElapsedMilliseconds.ToString());
s = new Stopwatch();
rnd = new Random();
Console.WriteLine("Расчет с промежуточной переменной...");
s.Start();
for (i = 0; i < N; i++)
{
x = rnd.NextDouble() * 10.0;
y = rnd.NextDouble() * 5.0;
t=x + y;
z = Magic(t, t);
if (z == 1111.11) Console.WriteLine("Magic!");
}
s.Stop();
Console.WriteLine("t=" + s.ElapsedMilliseconds.ToString());
Console.ReadKey();
}
}

Автор: VadimTagil