Сергей Губанов писал(а):
Если написать конструктор .... и инициализировать посредством него: g = new Data(1, 2, 3), то всё будет летать...
Хм, обознатушки перепрятушки. Там компилятор сильно оптимизировал вызов new Data(1, 2, 3) из-за того, что аргументы - константы. А вот если аргументы - не константы, а переменные, то ничего и не летает, а по прежнему тормозит.
Код:
MODULE TestPenalty;
  IMPORT Log, Services;
  
  TYPE
    Data* = RECORD
      x*, y*, z*: REAL
    END;
  VAR
    count: INTEGER;
  PROCEDURE Do (x: REAL); (* без инициализации выполняется 10.816 секунд *)
    VAR d: Data;
  BEGIN
    d.x := x; d.y := x + 1.0; d.z := x + 2.0; (* с этой инициализацией 12.408 секунд *)
    INC(count);
    IF x > 0.0 THEN Do(x - 1.0); Do(x - 1.0) END
  END Do;
  PROCEDURE Main*;
    VAR t: LONGINT; a: Data;
  BEGIN
    t := Services.Ticks();
    Do(28.0);
    t := Services.Ticks() - t;
    Log.String("t = "); Log.Int(SHORT(t));
    Log.String(", count = "); Log.Int(count);
    Log.Ln
  END Main;
END TestPenalty.
Код:
namespace ValueTypePenalty
{
  public struct Data
  {
    public double x, y, z;
    public Data (double x, double y, double z)
    {
      this.x = x; this.y = y; this.z = z;
    }
  }
  class Program
  {
    static int count = 0;
    static void Do (double x) // без инициализации выполняется 7.842 секунд
    {
      Data d = new Data(x, x + 1.0, x + 2.0); // с этой инициализацией 23.363 секунд
      count++;
      if (x > 0.0) {Do(x - 1.0); Do(x - 1.0);}
    }
    static void Main (string[] args)
    {
      int t = System.Environment.TickCount;
      Do(28.0);
      t = System.Environment.TickCount - t;
      System.Console.WriteLine("t = " + t + ", count = " + count);
      System.Console.ReadLine();
    }
  }
}
На (многократную) инициализацию структуры Data было затрачено времени:
Код:
12.408 - 10.816 =  1.592 секунд BlackBox Component Pascal
23.363 -  7.842 = 15.521 секунд .Net C#