Re[4]: Сравнил скорости работы. Результаты потрясают воображ
От: Сергей Губанов Россия http://sergey-gubanov.livejournal.com/
Дата: 13.11.04 20:51
Оценка: 3 (1)
Я немного модифицировал программы на Component Pascal и C#, после чего сравнил скорости их исполнения на моей домашней машине. Времена исполнения оказались сильно разными.

Вот исходный код программы на Component Pascal:
MODULE TestGC;

IMPORT StdLog, Services;
    
PROCEDURE f(N: INTEGER);
TYPE Objects = POINTER TO ARRAY OF Object;
     Object  = POINTER TO RECORD Refs: Objects END;
VAR X, a: Objects; i,j: INTEGER;
BEGIN
  NEW(X, N);
  FOR i := 0 TO N-1 DO NEW(X[i]) END;
  FOR i := 0 TO N-1 DO
    NEW(a, N);
    FOR j := 0 TO N-1 DO a[j] := X[j] END;
    X[i].Refs := a;
  END;
END f;

PROCEDURE Main*();
CONST N = 5000;
VAR n: INTEGER; t: LONGINT;
BEGIN
  StdLog.String("first memory allocation..."); f(N); StdLog.Ln();
  StdLog.String("start");
  t := Services.Ticks();
  FOR n := 1 TO 10 DO f(N) END;
  t := (Services.Ticks() - t) DIV 10;
  StdLog.String("t = "); StdLog.Int(t); StdLog.String(" ms");
  StdLog.Ln();
END Main;

END TestGC.

Обратите внимание на "холостой" вызов f(N); в самом начале процедуры Main. Это я сделал для того, чтобы BlackBox один раз захватил память у Windows, а в следующие разы чтобы измерять именно сборку мусора. Самый первый вызов f(N) всегда длится дольше чем все остальные (2 секунды в первый раз супротив 1.7 секунды во все остальные разы).


А вот аналогичный предыдущему код, который я написал на C#. Сразу предупреждаю, что в C# я не специалист, поэтому если вдруг я что-то написал не так, то прошу сразу ногами не пинать...

namespace TestGC
{
    class Object
    {
        public Object[] Refs;
    }

    class Program
    {
          static void Main(string[] args)
        {   
            const int N = 5000;
            System.Console.WriteLine("first memory allocation..."); f(N);
            System.Console.WriteLine("Start...");
            long t = System.Environment.TickCount;
            for (int i = 0; i < 10; i++) f(N);
            t = (System.Environment.TickCount - t) / 10;
            System.Console.WriteLine("t = {0}", t); 
            System.Console.ReadLine();
        }

        private static void f(int N)
        {
            Object[] X = new Object[N];
            for (int i = 0; i < N; i++) X[i] = new Object();
            for (int i = 0; i < N; i++)
            {
                Object[] a = new Object[N];
                for (int j = 0; j < N; j++) a[j] = X[j];
                X[i].Refs = a; 
            }
        }
    }
}

Влад использовал для измерения времени "PerfCounter", который я у себя не нашел, поэтому для измерения времени я использовал System.Environment.TickCount. Думаю, что это не сильная модификация программы Влада. Еще Object у меня не struct, а class (когда я делал ее struct, то у меня во время выполнения случалась ошибка — чего-то там не могло загрузить тип TestGC.Object из сборки TestGC). И еще есть небольшая модификация внутри главного цикла по сравнению с программой Влада. А вобщем, эта программа есть тупой буквальный перевод первой программы с языка Component Pascal на язык C#.




Результаты.
Прежде чем привести результаты, во-первых, опять же напомню, что в C# я не специалист, так что вполне мог написать кривую программу и скорость ее работы ни о чем говорить не может кроме кривизны моих рук. Во-вторых, есть следующее интересное наблюдение: Дело в том, что структура из N=5000 взаимно ссылающихся друг на друга объектов (число связей = N^2) занимает примерно 4*N^2 = 100 мегабайтов памяти. Так вот, BlackBox захватывал у Windows эти 100 мегабайтов и работал с ними "не прося добавки". Программа написанная на C# под .NET вела себя прямо противоположным образом. У меня на компе стоит 448 мегабайтов оперативки, так вот эта программа периодически захватывала все новые и новые 100 мегабайтов до тех пор пока оперативная память ни кончалась, а потом, видимо вызывался дотнетовский сборщик мусора и количество используемой памяти падало до минимума, затем серия захватов памяти по 100 мегабайтов повторялась вновь. Короче, результаты следующие:
Component Pascal     BlackBox 1.4                 t = 1.691 сек, 
C#                   MS Visual Studio .NET 2003   t = 6.375 сек,

BlackBox оказался в 6.375/1.691 = 3.77 быстрее чем .NET

Windows XP SP1, машина Celeron 1100 Coppermain 128Kb, DIMM 448Mb PC100.

Такую большую разницу я могу объяснить только тем что BlackBox только один раз взял 100 мегабайтов, а .NET то и дело захватывал по 100 мегабайтов пока вся оперативная память не исчерпывалась, а потом возвращал ее обратно повторяя все это вновь и вновь.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.