Rambler's Top100
"Knowledge itself is power"
F.Bacon
Поиск | Карта сайта | Помощь | О проекте | ТТХ  
 Базарная площадь
  
О разделе

Основная страница

Группы обсуждений


Тематический каталог обсуждений

Архив

 
 К н и г и
 
Книжная полка
 
 
Библиотека
 
  
  
 


Поиск
 
Поиск по КС
Поиск в статьях
Яndex© + Google©
Поиск книг

 
  
Тематический каталог
Все манускрипты

 
  
Карта VCL
ОШИБКИ
Сообщения системы

 
Форумы
 
Круглый стол
Новые вопросы

 
  
Базарная площадь
Городская площадь

 
   
С Л С

 
Летопись
 
Королевские Хроники
Рыцарский Зал
Глас народа!

 
  
ТТХ
Конкурсы
Королевская клюква

 
Разделы
 
Hello, World!
Лицей

Квинтана

 
  
Сокровищница
Подземелье Магов
Подводные камни
Свитки

 
  
Школа ОБЕРОНА

 
  
Арсенальная башня
Фолианты
Полигон

 
  
Книга Песка
Дальние земли

 
  
АРХИВЫ

 
 

Сейчас на сайте присутствуют:
 
  
 
Во Флориде и в Королевстве сейчас  07:00[Войти] | [Зарегистрироваться]
Обсуждение темы:
Сравнение компиляторов

Соответствует ли действительности то, что компилятор Object Pascal в Delphi лучше компилятора C++ в C++Builder? Для эксперимента я создал два проекта на С++Builder и Delphi соответственно, и всего навсего в процедуре обрабатывающей нажатие на кноку задал пустой цикл от 1 до 1 миллиарда:

В С++Builder соответсвующая функция выглядела сл. образом:
void __fastcall TForm1::Button1Click(TObject *Sender)
{

 for (int i = 0; i < 1000000000; i++);

}
а в Delphi соответствующая процедура выглядела так:
procedure TForm1.Button1Click(Sender: TObject);

 var i : integer;

begin

 for i:= 0 to 1000000000 do;

end;
И что же оказывается - Программа на Delphi выполняется в 5 раза быстрее(4 сек., а на С++Builder - 20 cек.)! ?? Тогда я решил выяснить в чём разница в конечном коде, генерируемом компиляторами C++Builder и Delphi. Для этого я просто установил точки останова(breakpoint) напротив циклов и во время выполнения заглянул в Debug Windows/CPU и что оказалось:

код сгенерированный компилятором С++Builder, соответсвующий пустому циклу в ассемблерном представлении выглядит сл. образом:
xor edx, edx

mov [ebp-0x34], edx
inc dword ptr [ebp-0x34]
mov ecx, [ebp-0x34]
cmp ecx, 0x3b9aca00
jl -0x0e
А у Delphi получился такой код:
mov edx, $3b9aca00
dec edx
jnz TForm1.Button1Click + $5
Т.О. отсюда уже понятны причины почему программа на Delphi быстрее выполняется. Помимо того что бросается в глаза большее количество команд видно ещё принципиальное отличие - в коде первой программы в качестве переменной-счётчика используется ячейка памяти, а компилятор Delphi сгенерировал код в котором используется регистр процессора в качестве счётчика. Хорошо, можно и устранить последнее отличее сл. образом:
void __fastcall TForm1::Button1Click(TObject *Sender)
{

 for (register int i = 0; i < 1000000000; i++);

},
т.е. перед переменной-счётчиком i указали спецификатор register, предварительно в настройках компилятора разрешив использование Register Variables(Project/Options/Advanced Compiler/Register Variables). Действительно тогда код сгенерированный компилятором С++Builder изменится к виду:
mov eax, 0x3b9aca00
dec eax
test eax, eax
jnle -0x05
Как видим теперь уже почти не отличается от кода сгенерированного компилятором Delphi! За исключением одной лишней команды - test eax, eax(зачем она нужна??) и команды jnle вместо jnz. Вот за счёт этой лишней команды test eax, eax, кот. выполняется в цикле и увеличивается время выполнения (на 15 сек. становится дольше). Так что же это?! Низкое качество генерируемого кода компилятором C++Builder в сравнении с компилятором Delphi?? Специалисты! Помогите! Проясните ситуацию. Какой же компилятор лучше - C++Builder или компилятор Delphi?? Или возможно как-то добиться той же эффективности кода, настроив как-то компилятор С++ в С++Builder? Очень благодарен за ответы с пояснением!

PS Ещё заметил такой прикол, что если в С++Builder вместо просто цикла от 1 до миллиарда использовать 2 равносильных цикла, т.е. один вложенный в другой: внешний от 1 до миллиона, а внутренний от 1 до тысячи, вот тогда как ни парадоксально скорость выполнения 2х циклов быстрее в 5 раз чем просто одного от 1 до миллиарда! Т.Е. вариант:
 for (int i = 0; i < 1000000000; i++);
много медленее, чем вариант:
for(int i = 1; i < 1000000; i++)
    for(int j = 1; j < 1000; j++);
!!?? Получается что если нам надо выполнить какие-то действия в программе миллиард раз, нужно это сделать не в одном цикле, а задать внешний цикл от 1 до миллиона и внутренний от 1 до тысячи, например, и в теле внутреннего описать все действия!!??

Максим

Количество сообщений на странице

Порядок сортировки сообщений
Новое сообщение вверху списка (сетевая хронология)
Первое сообщение вверху списка (обычная хронология)

Перейти на конкретную страницу по номеру


Всего в теме 346 сообщений

Добавить свое сообщение

Отслеживать это обсуждение


Смотрите также обсуждения:
Средства разработки. Языки программирования.
  • Delphi 4 or Delphi 5
  • Что приобрести в качестве средства разработки?
  • Delphi6
  • Delphi vs PowerBuilder
  • Вот и вышла Delphi 7... Вы рады?
  • Функциональное программирование

  • <<<... | 306—297 | 296—287 | 286—277 | ...>>>
    Всего сообщений в теме: 346; страниц: 35; текущая страница: 6


    № 296   21-06-2007 02:59 Ответить на это сообщение Ответить на это сообщение с цитированием
    Ответ на »сообщение 295« (Антон Григорьев)
    ___________________________

    Ответ на »сообщение 294« (al_mt)
    ___________________________

    Вообще-то было бы странно, если бы .Net приложение работало бы быстрее нативного кода %)

    Не все с этим согласны :)

    ... может оптимизировать финальный исполняемый код, используя инструкции конкретного машинного кода, предназначенные для конкретного процессора."

    А вот эта вот байда - чистый маркетинг. заметьте оговорку "может" :)))) В принципе может. На деле получается, что время компиляции прибавляется к времени исполнения %) %))))))


    № 295   21-06-2007 02:16 Ответить на это сообщение Ответить на это сообщение с цитированием
    Ответ на »сообщение 294« (al_mt)
    ___________________________

    Вообще-то было бы странно, если бы .Net приложение работало бы быстрее нативного кода %)

    Не все с этим согласны :)

    "<...> Это объясняет, почему можно рассчитывать на то, что выполнение управляемого кода IL будет почти настолько же быстрым, как и выполнение родного машинного кода. Однако это не объясняет того, почему Microsoft ожидает повышения производительности. Причина состоит в том, что поскольку финальная стадия компиляции происходит во время выполнения, JIT-компилятор на этот момент уже знает, на каком типе процессора запущена программа. А это значит, что он может оптимизировать финальный исполняемый код, используя инструкции конкретного машинного кода, предназначенные для конкретного процессора."

    Кристиан Нейгел, Билл Ивьен, Джей Глинн, Карли Уотсон, Морган Скиннер, Фллен Джонс "C# 2005 для прфессионалов" М.: Издательский дом "Вильямс", 2007, страница 46.


    № 294   21-06-2007 00:46 Ответить на это сообщение Ответить на это сообщение с цитированием
    Ответ на »сообщение 293« (Марина)
    ___________________________

    >Интересно всё таки какой нибудь более сложный тест придумать, чтобы проверить насколько сильно этот баг >влияет на скорость выполнения реальных приложений.

    На Gamedev народ тоже столкнулся с проблеммой Delphi 10 работает медленнее чем Delphi 7.

    http://www.gamedev.ru/flame/forum?id=66154&page=12

    Вообще-то было бы странно, если бы .Net приложение работало бы быстрее нативного кода %)


    № 293   20-06-2007 22:39 Ответить на это сообщение Ответить на это сообщение с цитированием
    >Интересно всё таки какой нибудь более сложный тест придумать, чтобы проверить насколько сильно этот баг >влияет на скорость выполнения реальных приложений.

    На Gamedev народ тоже столкнулся с проблеммой Delphi 10 работает медленнее чем Delphi 7.

    http://www.gamedev.ru/flame/forum?id=66154&page=12


    № 292   03-04-2007 10:06 Ответить на это сообщение Ответить на это сообщение с цитированием
    Ответ на »сообщение 291« (DRON)
    ___________________________

    Ну и хрен с ним (оптимизатором)

    "Wipe your hand across your mouth, and laugh"

    T.S.Eliot


    № 291   03-04-2007 06:11 Ответить на это сообщение Ответить на это сообщение с цитированием
    Ответ на »сообщение 290« (Cepгей Poщин)
    ___________________________
    Я тут слегка погуглин и нашёл вот это http://qc.codegear.com/wc/qcmain.aspx?d=8695, действительно ошибка в кодогенератор была внесена именно в D7Update1 и с тех пор не исправлена, хотя и помечена как "Closed в D2005".
    Выражается она в том что оптимизатор тупит и забывает про существование некоторых регистров, в данном случае про ebp, а это приводит к интенсивным обменам с памятью (стеком). Те у кого Delphi7 ещё могут заменить DCC32.exe и DCC70.dll на оригинальные, с диска, остальные вообще в пролёте.
    Правда должен сказать, что это заметно только на довольно специфическом коде где много одновременно задействованных локальных переменных и нет ничего кроме обменов и простейших операций, а если выбрать алгоритм немного посложнее, то и D5 и D7 будут генерить одинакого плохой код.
    Интересно всё таки какой нибудь более сложный тест придумать, чтобы проверить насколько сильно этот баг влияет на скорость выполнения реальных приложений.
     DRON


    № 290   03-04-2007 02:43 Ответить на это сообщение Ответить на это сообщение с цитированием
    По поводу сравнения скорости работы Delphi5 и BDS2006 см. »сообщение 250 в теме №377 на БП«
    Вот мои печальные выводы:
    Действительно вынос кода в процедуру и замена for на while деает некоторое улучшение, но тем не менее BDS2006 работает медленнее чем Delphi5 в 1,4..1,6 раза. Было бы еще понятно, если бы это происходило на каком-нибудь Pentium-90. Но тест производился на Pentium4 3GHz
    Вот тестовая программа:

    program TestTime;
    {$APPTYPE CONSOLE}
    uses
      Sysutils,
      Windows
      ;

    var
      razmer:integer;
      b:array[1..20] of integer;
      Time1,Time2,nomvar,d,m,kl,min,obmen:integer;
    procedure CallFor;
    var  b:array[1..20] of integer;
        d,m,kl,min,obmen:integer;
    begin
      for d:=1 to 20 do
        b[d]:=d;
      nomvar:=0;
      while True do
        begin
          nomvar:=nomvar+1;
          for m:=razmer downto 2 do
            if b[m]>b[m-1] then
              break;
          if m=1 then
            Break;
          obmen:=m-1;
          for min:=obmen+1 to razmer do
            if (b[min]<b[m]) and (b[min]>b[obmen]) then
              m:=min;
          min:=b[obmen];
          b[obmen]:=b[m];
          b[m]:=min;
          for d:=obmen+1 to razmer-1 do
            begin
              m:=d;
              for kl:=d+1 to razmer do
                if b[kl]<b[m] then
                  m:=kl;
              min:=b[m];
              b[m]:=b[d];
              b[d]:=min;
            end;
        end;
    end;

    procedure CallWhile;
    var  b:array[1..20] of integer;
        d,m,kl,min,obmen:integer;
    begin
      for d:=1 to 20 do
        b[d]:=d;
      nomvar:=0;
      while True do
        begin
          nomvar:=nomvar+1;
          for m:=razmer downto 2 do
            if b[m]>b[m-1] then
              break;
          if m=1 then
            Break;
          obmen:=m-1;
          for min:=obmen+1 to razmer do
            if (b[min]<b[m]) and (b[min]>b[obmen]) then
              m:=min;
          min:=b[obmen];
          b[obmen]:=b[m];
          b[m]:=min;
          for d:=obmen+1 to razmer-1 do
            begin
              m:=d;
              kl:= d + 1;
              while kl <= razmer do
              begin
                if b[kl]<b[m] then
                  m:=kl;
                inc(Kl);
              end;
              min:=b[m];
              b[m]:=b[d];
              b[d]:=min;
            end;
        end;
    end;


    begin
      Sleep(1000);
      razmer:=12;
      CallFor;
      CallWhile;

      razmer:=13;
      Time1:=GetTickCount;
      for d:=1 to 20 do
        b[d]:=d;
      nomvar:=0;
      while True do
        begin
          nomvar:=nomvar+1;
          for m:=razmer downto 2 do
            if b[m]>b[m-1] then
              break;
          if m=1 then
            Break;
          obmen:=m-1;
          for min:=obmen+1 to razmer do
            if (b[min]<b[m]) and (b[min]>b[obmen]) then
              m:=min;
          min:=b[obmen];
          b[obmen]:=b[m];
          b[m]:=min;
          for d:=obmen+1 to razmer-1 do
            begin
              m:=d;
              for kl:=d+1 to razmer do
                if b[kl]<b[m] then
                  m:=kl;
              min:=b[m];
              b[m]:=b[d];
              b[d]:=min;
            end;
        end;
      Time2:=GetTickCount;
      Writeln('Count: '+IntToStr(nomvar));
      Writeln('Time: '+IntToStr(Time2-Time1)+'(ms)');
      Time1:=GetTickCount;
      CallFor;
      Time2:=GetTickCount;
      Writeln('Count: '+IntToStr(nomvar));
      Writeln('Time: '+IntToStr(Time2-Time1)+'(ms)');
      Time1:=GetTickCount;
      CallWhile;
      Time2:=GetTickCount;
      Writeln('Count: '+IntToStr(nomvar));
      Writeln('Time: '+IntToStr(Time2-Time1)+'(ms)');
      Readln;
    end.


    Может я что-то делаю не так?
     Cep


    № 289   14-06-2006 04:41 Ответить на это сообщение Ответить на это сообщение с цитированием
    Прочитал сообщение Максима и удивился!!! Кто же ТАК сравнивает компиляторы, дорогой товарищ :) Господа из Борланд инфаркт бы схватил, если бы узнали о Ваше методике. Компиляторы сравниваются на реальной задаче, где активно используются мат.вычисления, постоянно используется оперативная память... Просто запустить цикл, и все? Как-то в Компьютерном обозрении была опубликована статья на тему сравнения компиляторов. Автор использвал задачу решения дифференциальных уравнений численными методами. Там был Delphi, Borland C++, MSVC++, GCC, Fortran, Intel C++, VB(!) и некоторые другие... Так вот по рещультатам забега первое место занял Intel Fortran, за ним Intel C++, GCC и все остальные. Delphi и Borland C++ показали одинаковый результат.

    Кстати, в Borland C++ нужно еще выбрать конфигурацию проекта Release, вот тогда все будет работать очень быстро, быстрее чем в Delphi.

    Сам я тоже такими вещами баловался когда-то... Только тест немного посложнее делал: в цикле давал вычислительную нагрузку, потом рекурсивно реализовывал вычисление числа сочетаний из n по k (C(n, k)), в общем в таком духе :) Так у меня C++ всегда ощутимо быстрее оказывался. Такие дела.

    Если Вам нужна качественная оптимизация кода и поддержка современых процессоров - выбирайте компилятор Intel, не пожалеете! Он многое умеет (почитайте спецификации на сайте ИНтел), хотя и денег стоит.
    p.s.: это не реклама


    № 288   Удалено модератором


    № 287   08-07-2005 07:20 Ответить на это сообщение Ответить на это сообщение с цитированием
    Просто факт.

    MSVC7 и C# используют в FPU Control Word
    дефолтное значение (PrecisionMode = double)
    BC++ и Delphi - PrecisionMode = extended
    Это, что жульничество MS или недоработка Borland?
    Ведь (PrecisionMode = double) ускоряет вычисления с
    плавающей точкой процентов на 10 по отношению к
    (PrecisionMode = extended).


    <<<... | 306—297 | 296—287 | 286—277 | ...>>>
    Всего сообщений в теме: 346; страниц: 35; текущая страница: 6


    Добавить свое сообщение

    Отслеживать это обсуждение

    Дополнительная навигация:
    Количество сообщений на странице

    Порядок сортировки сообщений
    Новое сообщение вверху списка (сетевая хронология)
    Первое сообщение вверху списка (обычная хронология)

    Перейти на конкретную страницу по номеру
      
    Время на сайте: GMT минус 5 часов

    Если вы заметили орфографическую ошибку на этой странице, просто выделите ошибку мышью и нажмите Ctrl+Enter.
    Функция может не работать в некоторых версиях броузеров.

    Web hosting for this web site provided by DotNetPark (ASP.NET, SharePoint, MS SQL hosting)  
    Software for IIS, Hyper-V, MS SQL. Tools for Windows server administrators. Server migration utilities  

     
    © При использовании любых материалов «Королевства Delphi» необходимо указывать источник информации. Перепечатка авторских статей возможна только при согласии всех авторов и администрации сайта.
    Все используемые на сайте торговые марки являются собственностью их производителей.

    Яндекс цитирования