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

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

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


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

Архив

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


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

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

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

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

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

 
   
С Л С

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

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

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

Квинтана

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

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

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

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

 
  
АРХИВЫ

 
 

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

Соответствует ли действительности то, что компилятор 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... Вы рады?
  • Функциональное программирование

  • <<<... | 46—37 | 36—27 | 26—17 | ...>>>
    Всего сообщений в теме: 346; страниц: 35; текущая страница: 32


    № 36   21-11-2001 15:05 Ответить на это сообщение Ответить на это сообщение с цитированием
    Пользователя не интересуют приложения - его интересует осмысленные действия, которые он выполняет.
    "Загрузить Word" - не осмысленное действие. Осмысленное действие - "Открыть документ".

    Никто не сказал что jvm будет стартовать на каждое отдельное действие данного пользователя....


    № 35   21-11-2001 14:54 Ответить на это сообщение Ответить на это сообщение с цитированием
    > iZEN
    > Нет не надо, у нас тесты на время испонения циклов, а не на общее время работы приложений.

    Кто сказал что тесты не на время работы приложения? Пользователя то интересует именно это.
    И если перед тем, как за 10 секунд выполнить цикл, десять минут будет выполнятся компиляция, он выберет программу на дельфи, которая загрузится и выпонится за 14 секунд.


    № 34   21-11-2001 14:54 Ответить на это сообщение Ответить на это сообщение с цитированием
    > iZEN
    > Нет не надо, у нас тесты на время испонения циклов, а не на общее время работы приложений.

    Кто сказал что тесты не на время работы приложения? Пользователя то интересует именно это.
    И если перед тем, как за 10 секунд выполнить цикл, десять минут будет выполнятся компиляция, он выберет программу не дельфи, которая загрузится и выпонится за 14 секунд.


    № 33   20-11-2001 20:47 Ответить на это сообщение Ответить на это сообщение с цитированием
    Максим вот код которые выдает четвёртый билдер при полной оптимизации:

    xor      eax,eax
    @8:
    @10:
    inc      eax
    cmp      eax,1000000000
    jl        short @8

    Я что-то разницы с дельфи не вижу


    № 32   19-11-2001 23:41 Ответить на это сообщение Ответить на это сообщение с цитированием
    to evgeg.
    Нет не надо, у нас тесты на время испонения циклов, а не на общее время работы приложений.
    Нужно учитывать "чистое" время выполнения кода, то есть так как и с Delphi-программой.

    to Peter Taran.
    Спасибо за разъяснения.
     iZEN


    № 31   19-11-2001 13:13 Ответить на это сообщение Ответить на это сообщение с цитированием
    Хочу заметить, что время компиляции при запуске в маш. код (Java) надо тоже учитывать.


    № 30   19-11-2001 06:20 Ответить на это сообщение Ответить на это сообщение с цитированием
    to iZEN.

    Такие секунды потому, что если исполнение началось в 59 секунд, а закончилось -- в 03 секунды (уже следующей минуты), то произойдёт переполнение при вычитании.

    Правильно измерять время так:

    var
      Time: LongWord;
    begin
      Time := GetTickCount();
      . . .
      Time := GetTickCount() - Time;
    end;

    Значение в Time будет в милисекундах. А ещё лучше -- QueryPerformanceCounter, но это уже на любителя :-)


    № 29   19-11-2001 03:26 Ответить на это сообщение Ответить на это сообщение с цитированием
    Хороший разговор получается.
    Каждый о своем. Кому что ближе и любимее то это и хвалит!
    Помоему опять речь идет о вкусах.
    Обычный пользователь Вашей оптимизации не заметит, а на каком компиляторе выполнен машинный код - ему вообще до фени.
    На вопросы надо глядеть шире, а к людям (пользователям) быть ближе.
    Хотя со многими я согласен. Если компилятор не может оптимально сделать код сам, то ему наверное необходимо помочь. Все-таки решающим должно быть слово разработчика. Упавать полностью на компилятор тоже не надо.


    № 28   18-11-2001 23:30 Ответить на это сообщение Ответить на это сообщение с цитированием
    1. Программно-аппаратное обеспечение.
    CPU: Duron 700 МГц
    FSB: 200 МГц
    RAM: 128Мб SDRAM133/CAS=2/6нс.
    Система: Windows2000Pro RUS
    IDEs: Borland Delphi 5.0 Enterprise; Borland JBuilder 5.0 Personal (JDK1.3.0_02 Java Compiler).


    2. Коды тестов:

    Borland Delphi 5.0 Enterprise:

    procedure TForm1.Test1ButtonClick(Sender: TObject);
    var
      t: TDateTime;
      i: Integer;
      h, m, s0, s, ms0, ms: Word;
      ds, dms: Word;
    begin
      t := Time;
      DecodeTime(t, h, m, s0, ms0);
      Label1.Caption := 'Одиночный цикл с оптимизацией компилятором.';
      for i := 1 to 1000000000 do ;
      t := Time;
      DecodeTime(t, h, m, s, ms);
      ds := s - s0;
      Label2.Caption := 'Длительность: ' + IntToStr(ds) + ' с ';
    end;

    procedure TForm1.Test2ButtonClick(Sender: TObject);
    var
      t: TDateTime;
      b, c: Integer;
      h, m, s0, s, ms0, ms: Word;
      ds, dms: Word;
    begin
      c := 0;
      t := Time;
      DecodeTime(t, h, m, s0, ms0);
      Label1.Caption := 'Одиночный цикл без оптимизации компилятором.';
      for b := 1 to 1000000000 do c := b - 1;
      t := Time;
      DecodeTime(t, h, m, s, ms);
      ds := s - s0;
      Label2.Caption := 'Длительность: ' + IntToStr(ds) + ' с ';
      Label3.Caption := 'Переменные цикла на выходе: ' + 'b=' + IntToStr(b) + '; c=' + IntToStr(c);
    end;

    procedure TForm1.Test3ButtonClick(Sender: TObject);
    var
      t: TDateTime;
      d, e, f, g: Integer;
      h, m, s0, s, ms0, ms: Word;
      ds, dms: Word;
    begin
      t := Time;
      DecodeTime(t, h, m, s0, ms0);
      Label1.Caption := 'Тройной цикл без оптимизации компилятором.';
      for d := 1 to 1000 do begin
        g := d - 1;
        for e := 1 to 1000 do
          for f := 1 to 1000 do ;
      end;
      t := Time;
      DecodeTime(t, h, m, s, ms);
      ds := s - s0;
      Label2.Caption := 'Длительность: ' + IntToStr(ds) + ' с ';
      Label3.Caption := 'Переменные цикла на выходе: ' + 'd=' + IntToStr(d) + '; e=' + IntToStr(e) + '; f=' + IntToStr(f) + '; g=' + IntToStr(g);
    end;


    JBuilder5Personal (Java JDK1.3.0_02):

    public class Untitled1 {

      public Untitled1() {
      }
      public static void main(String[] args) {
        {
          System.out.println("Одиночный цикл с оптимизацией компилятором.");
          int a = 0;
          long t1 = System.currentTimeMillis();
          for (a = 0; a < 1000000000; a++);
          t1 = System.currentTimeMillis() - t1;
          System.out.println("Длительность: " + t1 + " мс");//Длительность: 4346 мс
          System.out.println("Переменная цикла на выходе: " + "a=" + a);
        } {
          System.out.println("Одиночный цикл без оптимизации компилятором.");
          int b = 0, c = 0;//Объявляем новые переменные -- исключаем кэширование старых
          long t2 = System.currentTimeMillis();
          for(b = 0; b < 1000000000; b++) c = b - 1;//Исключаем оптимизацию компилятором
          t2 = System.currentTimeMillis() - t2;
          System.out.println("Длительность: " + t2 + " мс");//Длительность: 6720 мс
          System.out.println("Переменные цикла на выходе: " + "c=" + c + "; " + "b=" + b);
        } {
          System.out.println("Тройной цикл без оптимизации компилятором.");
          int d = 0, e = 0, f = 0, g = 0;//Объявляем новые переменные -- исключаем кэширование старых
          long t3 = System.currentTimeMillis();
          for(d = 0; d < 1000; d++) {
            g = d - 1;//Исключаем оптимизацию компилятором
            for(e = 0; e < 1000; e++)
              for(f = 0; f < 1000; f++);
          }
          t3 = System.currentTimeMillis() - t3;
          System.out.println("Длительность: " + t3 + " мс");//Длительность: 7260 мс
          System.out.println("Переменные цикла на выходе: " + "d=" + d + "; " + "e=" + e + "; " + "f=" + f + "; " + "g=" + g);
        }
      }
    }


    Результат выполнения в Delphi5.0:

    Одиночный цикл с оптимизацией компилятором.
    Длительность: 5 сек.

    Одиночный цикл без оптимизации компилятором.
    Длительность: 3 сек.

    Тройной цикл без оптимизации компилятором.
    Длительность: 3 сек.


    Результат выполнения в JBuilder5.0:

    Одиночный цикл с оптимизацией компилятором.
    Длительность: 4.3 с

    Одиночный цикл без оптимизации компилятором.
    Длительность: 6.7 с

    Тройной цикл без оптимизации компилятором.
    Длительность: 7.3 с


    3. Комментарии и выводы:
    0) При компиляции проекта включено "Debug Info", оптимизация выключена.
    1) Непонятно поведение программы на Delphi: иногда она выдавала длительность от 3 до 5 с во всех тестах, несколько раз аж 65480 с (что за глюк, ведь работала положенное время 3-5 с) ?!
    2) Delphi/Java -- паритет по одиночному циклу.
     iZEN


    № 27   18-11-2001 14:22 Ответить на это сообщение Ответить на это сообщение с цитированием
    НАРОД! Всем благодпрен за ответ, но я вношу поправку в свой вопрос, поскольку сразу не разобрался:

    Всё правильно. Понятно естественно почему такой код генерирует компилятор C++. Просто в языке Object Pascal цикл for - это проосто повторение n раз, а в С++ структура for гораздо более сложная: в ней можно указать условие окончания цикла любой сложности, а также изменять значение переменной-счётчика по любому закону, а просто структуры повторения n раз нет.
    Но почему компилятор С++ не оптимизирует такой простой случай цикла for от 1 до n при изменении переменной-счётчика на единицу в каждом цикле?(естественно что оптимизация включена). Ведь даже если в Pascal задать цикл while вместо for, то компилятор Object Pascal в Delphi оптимизирует такой вариант как протой случай, и выполнится программа с while так же быстро как и с for.
    Что действительно Borland дали маху с оптимизацией в компиляторе С++?

    Ещё раз благодарен за ответ!


    <<<... | 46—37 | 36—27 | 26—17 | ...>>>
    Всего сообщений в теме: 346; страниц: 35; текущая страница: 32


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

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

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

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

    Перейти на конкретную страницу по номеру
      
    Время на сайте: 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» необходимо указывать источник информации. Перепечатка авторских статей возможна только при согласии всех авторов и администрации сайта.
    Все используемые на сайте торговые марки являются собственностью их производителей.

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