Delphi консультации (бесплатно)

  • Автор теми Автор теми crghome
  • Дата створення Дата створення
Еще скажи, что небо голубое, потому-что поезд прибывает. Структурный язык разрабатывался по принципам ООП, и стал следующим шагом после процедурного. И по сей день его никто не отменил, и многие приложения на С++ используют такой стиль. Разница объектного языка в том, что он использует не наследование собственных объектов, а берет их из SDK. Все.
ООООО. приехали. Какая еще ориентация. Возможности дельфая безграничны. Он может даже делать апплеты, не говоря уже про b2b системы, интеграторы и макросы.
Мушчино я и по ранешним постам видел шовы *****ъ, но сейчас я вижу шо вы фееричный *****ъ.

Обоснование - у C# намного более мощная оптимизация при компиляции в машинный код JIT'ом.

Не, ну я конечно выбрал задачу в которой преимущество на стороне C#, не без этого. :rolleyes: Чтобы более красочно подчеркнуть глупость утверждения что C# медленный.
Есть задачи в которых C# все-же медленее чем си (за счет дополнительного контроля на ошибки в runtime), в основном это обработка больших массивов данных. В таких случаях удобно вынести код в модуль написанный на си.
Тест ниочем. Походу С# запихнул переменную управления циклом в регистр а остальные по чесному юзали стек.
 
Если в момент вызова фреймворк захочет скомпилить свежевызванный класс/почистить память будет бобо. Это главное

а что мешает вызвать метод заранее, на этапе инициализации например. чтобы он скомпилился, если это так важно. Таким образом второй вызов прийдется на уже откомпиленный метод ;)
 
а что мешает вызвать метод заранее, на этапе инициализации например. чтобы он скомпилился, если это так важно. Таким образом второй вызов прийдется на уже откомпиленный метод ;)
Ну да костыль же так удобен при ходьбе.:D
 
Тест ниочем. Походу С# запихнул переменную управления циклом в регистр а остальные по чесному юзали стек.

вот тут ты не прав, специально посмотрел результирующий код:

Код:
		s_value++;
00000000  push        ebp 
00000001  mov         ebp,esp 
00000003  cmp         dword ptr ds:[038014A4h],0 
0000000a  je          00000011 
0000000c  call        763A35FF 
00000011  inc         dword ptr ds:[038016C0h] 
	}

Код:
		for (int i = 0; i < 100; i++)
0000004c  xor         edx,edx 
0000004e  mov         dword ptr [ebp-0Ch],edx 
00000051  nop 
00000052  jmp         00000071 
			for (int j = 0; j < 10000000; j++)
00000054  xor         edx,edx 
00000056  mov         dword ptr [ebp-10h],edx 
00000059  nop 
0000005a  jmp         00000065 
				Foo();
0000005c  call        dword ptr ds:[03801F44h] 
			for (int j = 0; j < 10000000; j++)
00000062  inc         dword ptr [ebp-10h] 
00000065  cmp         dword ptr [ebp-10h],989680h 
0000006c  jl          0000005C 
		for (int i = 0; i < 100; i++)
0000006e  inc         dword ptr [ebp-0Ch] 
00000071  cmp         dword ptr [ebp-0Ch],64h 
00000075  jl          00000054
 
Я вот не нашел способа заставить delphi хранить переменную в регистрах. есть аналог cшного register?
 
Ну да костыль же так удобен при ходьбе.:D

а где костыль? Костыля нет. Если не хочется при первом вызове ждать компиляции метода, тогда весь код сборки можно заранее скомпилить с помощью ngen.exe ;)
 
Я вот не нашел способа заставить delphi хранить переменную в регистрах. есть аналог cшного register?

сишный аналог ничего не гарантирует =)
Delphi и без этого старается переменные в регистрах юзать. Подебагайте оптимизированный вариант проги, посмотрите сколлько переменных доступно )
 
похоже на то что Java просто выкидывает весь цикл, а это не честно
Честно-честно. Вы ведь приводили оптимизацию компилятора C# как преимущество...
Ну вот - на абсолютно тупом синтетическом тесте C# выиграл у C++/Delphi за счет оптимизации... а Java выиграла у C# тоже за счет оптимизации... Все справедливо :)
 
Протестил примеры на ноуте

шарп - 2200
си - 5086
делфай - 3510

Синтетику шарп хорошо дает, знаем знаем.
На реальном примере попробую, через месяцок отпишусь )
 
а где костыль? Костыля нет. Если не хочется при первом вызове ждать компиляции метода, тогда весь код сборки можно заранее скомпилить с помощью ngen.exe ;)
Ну да еще один костыль.

вот тут ты не прав, специально посмотрел результирующий код:

Код:
		s_value++;
00000000  push        ebp 
00000001  mov         ebp,esp 
00000003  cmp         dword ptr ds:[038014A4h],0 
0000000a  je          00000011 
0000000c  call        763A35FF 
00000011  inc         dword ptr ds:[038016C0h] 
	}

Код:
		for (int i = 0; i < 100; i++)
0000004c  xor         edx,edx 
0000004e  mov         dword ptr [ebp-0Ch],edx 
00000051  nop 
00000052  jmp         00000071 
			for (int j = 0; j < 10000000; j++)
00000054  xor         edx,edx 
00000056  mov         dword ptr [ebp-10h],edx 
00000059  nop 
0000005a  jmp         00000065 
				Foo();
0000005c  call        dword ptr ds:[03801F44h] 
			for (int j = 0; j < 10000000; j++)
00000062  inc         dword ptr [ebp-10h] 
00000065  cmp         dword ptr [ebp-10h],989680h 
0000006c  jl          0000005C 
		for (int i = 0; i < 100; i++)
0000006e  inc         dword ptr [ebp-0Ch] 
00000071  cmp         dword ptr [ebp-0Ch],64h 
00000075  jl          00000054
Ну так за счет чего тогда разница то? Делфаевский код и шовыросло можешь привести?
 
Код:
Project1.dpr.25: start := GetTickCount();
0041C39F E824CCFEFF       call GetTickCount
0041C3A4 A3D03E4200       mov [$00423ed0],eax
Project1.dpr.26: for i := 0 to 99 do
0041C3A9 33C0             xor eax,eax
0041C3AB A3D43E4200       mov [$00423ed4],eax
Project1.dpr.27: for j := 0 to 9999999 do
0041C3B0 33C0             xor eax,eax
0041C3B2 A3D83E4200       mov [$00423ed8],eax
Project1.dpr.28: Foo();
0041C3B7 E8E8D5FFFF       call System + $FCA72DF4
0041C3BC FF05D83E4200     inc dword ptr [$00423ed8]
Project1.dpr.27: for j := 0 to 9999999 do
0041C3C2 813DD83E420080969800 cmp [$00423ed8],$00989680
0041C3CC 75E9             jnz $0041c3b7
Project1.dpr.28: Foo();
0041C3CE FF05D43E4200     inc dword ptr [$00423ed4]
Project1.dpr.26: for i := 0 to 99 do
0041C3D4 833DD43E420064   cmp dword ptr [$00423ed4],$64
0041C3DB 75D3             jnz $0041c3b0
Project1.dpr.29: writeln(IntToStr(GetTickCount - start) + ' [ms]');
0041C3DD E8E6CBFEFF       call GetTickCount
0041C3E2 2B05D03E4200     sub eax,[$00423ed0]
0041C3E8 33D2             xor edx,edx

Delphi



ЗЫ пример на c с полной оптимизацией выдает 0 мс :D
 
Останнє редагування:
Код:
Project1.dpr.25: start := GetTickCount();
0041C39F E824CCFEFF       call GetTickCount
0041C3A4 A3D03E4200       mov [$00423ed0],eax
Project1.dpr.26: for i := 0 to 99 do
0041C3A9 33C0             xor eax,eax
0041C3AB A3D43E4200       mov [$00423ed4],eax
Project1.dpr.27: for j := 0 to 9999999 do
0041C3B0 33C0             xor eax,eax
0041C3B2 A3D83E4200       mov [$00423ed8],eax
Project1.dpr.28: Foo();
0041C3B7 E8E8D5FFFF       call System + $FCA72DF4
0041C3BC FF05D83E4200     inc dword ptr [$00423ed8]
Project1.dpr.27: for j := 0 to 9999999 do
0041C3C2 813DD83E420080969800 cmp [$00423ed8],$00989680
0041C3CC 75E9             jnz $0041c3b7
Project1.dpr.28: Foo();
0041C3CE FF05D43E4200     inc dword ptr [$00423ed4]
Project1.dpr.26: for i := 0 to 99 do
0041C3D4 833DD43E420064   cmp dword ptr [$00423ed4],$64
0041C3DB 75D3             jnz $0041c3b0
Project1.dpr.29: writeln(IntToStr(GetTickCount - start) + ' [ms]');
0041C3DD E8E6CBFEFF       call GetTickCount
0041C3E2 2B05D03E4200     sub eax,[$00423ed0]
0041C3E8 33D2             xor edx,edx

Delphi



ЗЫ пример на c с полной оптимизацией выдает 0 мс :D
Ну какбе код то неэквивалентен. Делфаевский for и С++ (он же C#) for это две большие разницы. Откуда там разница набегает так и не вкурю. Что не тот регистр успользуют чтоли?
Вообщем как и следовало ожидать - тест ниочем.
Слушай а если вынести код теста в процедуру че получиццо?
 
Останнє редагування:
речь идет об unmanaged си
 
В таком случае for от Delphi гораздо ближе чем for в C#
 
Благодарствую за открытие Америки.
Не думаю что это для тебя открытие. Походу тебе про этот факт говорили и не раз.:D

приведи опкод


Вот это вообще не понял.
C++.NET или С++?
Синтаксис цикла for в С++ и С# одинаков и смысл тоже, а в Delphi он отличается.

разница там набегает за счет того что у C# накладные расходы на вызов метода меньше всего
Бла бла бла. Конкретно объясните.
Я пока вижу 2 существенные разницы между выхлопом компилеров:
1. Использование разных регистров для инциализации счетчиков начальными значениями
2. В C# в качестве переменых управления циклом используются локальные переменные из стека (относительная адресация по EBP), а Delphi - глобальные (абсолютная адресация). Скорее всего в этом и есть причина. И если вынести код теста в отдельную процедуру, которую и вызывать из main, то и она будет устранена.
 
Не думаю что это для тебя открытие. Походу тебе про этот факт говорили и не раз.
Просто мне не очень интересно развивать полемику и тягаться в знаниях с более опытным, а честно я не представляю к чему ты придрался (если насчет сравнения с ооп, так это абстрактно - технологии то разные), да как то и не важно.
 
Назад
Зверху Знизу