Соответствует ли действительности то, что компилятор 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... Вы рады?
- Функциональное программирование
№ 326 28-08-2007 07:57 | |
Ответ на »сообщение 321« (panda)
___________________________
2. Почему результат этого вычисления в C++ получается НЕ равным результату этого вычисления в C#?
Видимо, потому, что в стандарте C++ отсутствуют правила, которые позволяют однозначно сказать, как будет вычислено это выражение, и разные комипляторы вычисляют его по-разному. Вам просто не повезло - вы нарвались на такой компилятор C++, который делает это не так, как C# :)))
№ 325 28-08-2007 06:56 | |
Ответ на »сообщение 323« (Alexander)
___________________________
забывал какого типа и к чему относится переменная Компилятор-то помнит. Если компилируется, значит, в первом приближении, они тех типов, каких надо.
Стоит наверно учитывать, что эти студенты программ раньше в глаза не видывали. Если бы они писали на C, уверяю, убились бы на смерть.
Многие (конечно не все) вещи паскаль контролирует сам, и явные ляпы (кстати бывают не только из-за криворукости) не позволит сделать еще на этапе компиляции. В C приходится полагаться только на революционную сознательность программиста.
№ 324 28-08-2007 05:59 | |
Ответ на »сообщение 322« (Alexander)
___________________________
Лично я не строю громоздких выражений, функций … .
Я делаю код читабельным.
Но так делают не все. Если язык позволяет ошибаться, кто-нибудь обязательно ошибется. В шутках "как прострелить ногу" и "как поймать льва в пустыне" есть доля правды.
№ 323 28-08-2007 05:50 | |
Да забыл сказать.
Мне давали переделывать диплом двух студентов.
Они писали прогу на Delphi. У некоторых процедур
и функций раздел var занимал пол моего экрана
(не думайте что смотрел исходник на PDA, разрешение
было 1024x768). Естественно прочитать было торудно.
Когда доходил до середины процедуры забывал какого
типа и к чему относится переменная, сколько вложений уже
в цикле и т.д.
Повторюсь что все зависит от чистоплотности программиста.
А скорость компилирования моего проекта действительно была
несколько минут, когда тот проект компилировался пол минуты.
№ 322 28-08-2007 05:34 | |
Ответ на »сообщение 321« (panda)
___________________________
Я не отрицаю что в Си можно написать лабуду.
Но конечный результат зависит от самого программиста,
от его чистоплотности. У меня есть исходники движка
Doom 3. Там выражений вроде i=++i + ++i; нет.
Лично я не строю громоздких выражений, функций … .
Я делаю код читабельным.
№ 321 28-08-2007 05:23 | |
Ответ на »сообщение 317« (Alexander)
___________________________
А мне сложнее читать Паскаль.
Тогда посчитайте в уме результат вычисления, которое я приводил:
int i=5;
i = ++i + ++i;
А потом ответьте, пожалуйста, честно на два вопроса:
1. Сколько времени у вас заняло это вычисление в уме?
2. Почему результат этого вычисления в C++ получается НЕ равным результату этого вычисления в C#?
№ 320 28-08-2007 05:03 | |
Ответ на »сообщение 317« (Alexander)
___________________________
А мне сложнее читать Паскаль. Да. Это аргумент :o) Крыть не чем.
По поводу сравнения скорости компиляции, могу привести пример из реальной жизни.
Мой знакомый когда компилирует проект на C++ обычно уходит "перекурить", я часто вместо того, чтобы искать место, где закончил редактирование нажимаю F9 и моментально оказываюсь на месте ошибки, т.е. там, где редактировал.
Полная перекомпиляция всего проекта у меня ни когда не превосходила 30 сек, а он успевает пообедать, погулять с собакой...
Конечно проекты и размеры разные, но определенные представления о скорости компиляции получить можно.
№ 319 28-08-2007 04:52 | |
Ответ на »сообщение 317« (Alexander)
___________________________
Единственная, известная мне корректная работа по сравнению ЯЗЫКОВ программирования:
http://www.uni-vologda.ac.ru/cs/syntax/ariphm.htm
Причем сравнение по единственному критерию - синтаксической сложности.
Для меня это очень важный показатель: мне необходимо иметь корректный транслятор языка в голове. Если для С это возможно, то для С++ категорически нет. Читая чужой код на С++ очень сложно сказать, как он будет работать.
Хотя ObjectPascal по синтаксической сложности уже не уступает C++, в основе лежат достаточно четкие правила и чужой текст читается легче. Может быть потому, что OP ориентирован на определенную методологию программирования, а С++ позволяет смешивать различные парадигмы произвольным образом.
Сравнений компиляторов довольно много, но все они довольно субъективны.
Особенно это касается трудоемкости написания. Попробуйте сравнить трудоемкость написания письма на родном и иностранном языке. А где найти программиста, для которого С и Паскаль были бы одинаково родными? Если же сравнивать аналогичные проекты разных групп, то окажется, что выбор языка далеко не самое важное: трудоемкость гораздо сильнее зависит от проектирования, организации работы, квалификации персонала и т.д.
№ 318 28-08-2007 04:24 | |
Ответ на »сообщение 312« (Alexander)
___________________________
удобность синтаксиса C++. По моему глубокому убеждению это как раз один из его главных недостатков.
Рассомтрим приведенный в теме пример. Не надо быть полиглотом, чтобы перевести и запомнить слова procedure, begin, end. Оператор присваивания позаимствован из математики и т.д.
Если бы человек писал реферат, то заголовок мог бы иметь следующий вид:
Глава 1.2(...)
Процедура установка банок. Приглашение больного
Т.е. шаблон понятен, и не нуждается в запоминании.
void __fastcall как можно перевести?
Два подчеркивания, два двоеточия у людей с ослабленным зрением (или с бодуна, или просто от недосыпа) могут слится в одно, или в три. Фигурная скобка, особенно когда их много легко путаются с обычными.
Значок * в Pas всегда обозначает умножение, и это в общем-то интуитивно понятно.
А как интуитивно догадаться, что обозначает TObject *Sender? Нормальному программисту не придет в голову обозвать переменную O, или _nil, а здесь тоже самое как бы нормально.
Далее по цыклу:
В научном языке есть правило, что малосущественная информация не должна перекрывать основную. Например сетка должна быть тоньше чем график, а шкала не должна наползать на график. Точки над ё ставятся только если существует возможность разного прочтения, т.е. очень редко.
Здесь слова int и i++ в 99% случаев не несут ни какой информации с точки зрения понимания алгоритма но засоряют код.
Опять же интуитивно непонятно почему в одних случаях используется фигурная, а в других случаях круглая скобка.
P.S. Опс. пока сочинял, за меня уже ответили. Да ладно, жалко удалять :o)
№ 317 28-08-2007 03:57 | |
А мне сложнее читать Паскаль.
А есть ли инфа в инете следующего типа:
Сравнение компиляторов
1) Для сравнения взяты компиляторы Delphi, C++Builder, Microsoft Visual C++
2) Сравниваются написанные на них различные типы проектов (работа с СУДБ, 3D движок, …)
3) Сравнение идет по следующим критериям: скорость компиляции, скорость выполнения, трудоемкость написания и др.
Добавить свое сообщение
Отслеживать это обсуждение
Дополнительная навигация: |
|