Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2007.12.09;
Скачать: CL | DM;

Вниз

Объясните пожалуйста дельфисту, что такое шаблоны в Си?   Найти похожие ветки 

 
homm ©   (2007-11-01 14:48) [40]

> [39] wendy parkinson   (01.11.07 14:47)
> Но у C# тоже есть один большой недостаток. 20 мегабайтный :)

В версии 3.0 уже 35 вроде. И все больше и больше…


 
Alkid ©   (2007-11-01 14:50) [41]


> Но у C# тоже есть один большой недостаток. 20 мегабайтный
> :)

Видишь ли, это сейчас для всего, кроме embedded систем и мобильный платформ, на которых я ни разу не специализируюсь, уже ОЧЕНЬ МАЛЕНЬКИЙ недостаток. Даже если учесть распухание framework`а, этот недостаток остаётся маленьким.

Зато программировать на С# быстрее и приятнее. :)


 
Alkid ©   (2007-11-01 14:52) [42]


> короче, любая ветка в стиле "холивор" сводится к тому, что
> "любой овощ должен быть употреблен в надлежащее время...
> " или как там говорил незабвенный Козьма Прутков...
> :)

А ты думал я тут буду глотку рвать, в стиле "don"t underestimate power of the Dark Side, son"? :)
Кстати, Ega23 ещё в самом начале ветки высказался в том же духе :)


 
Anatoly Podgoretsky ©   (2007-11-01 14:55) [43]

> Alkid  (01.11.2007 14:44:35)  [35]

> По сравнению с остальным делом - не трудное. Но это примерно как заворачивать винты отвёрткой, когда есть электический шуруповёрт. Можно, но удобнее с шуруповёртом.

Руки бы оторвал, кому то приходится и откручивать их, например винчестеры и народный инструмент - зубило не применишь.


 
Anatoly Podgoretsky ©   (2007-11-01 14:57) [44]


> general purpose strongly typed languages

Ой не надо к этому с++ приписывать.


 
Alkid ©   (2007-11-01 14:57) [45]


> Руки бы оторвал, кому то приходится и откручивать их, например
> винчестеры и народный инструмент - зубило не применишь.

Значит пользовались шуруповёртами не той системы :)
У нас всё ок - админы с ними ходят, а мы, если что, отвёртками свои компы развиничаем :-)


 
homm ©   (2007-11-01 14:57) [46]

> [41] Alkid ©   (01.11.07 14:50)
> Видишь ли, это сейчас для всего, кроме embedded систем и
> мобильный платформ, на которых я ни разу не специализируюсь,
> уже ОЧЕНЬ МАЛЕНЬКИЙ недостаток.

Ага, уже любой пенсионер на свою пенсию и из любой деревни может выкачать из инета 30 метров. ;)


> [41] Alkid ©   (01.11.07 14:50)
> Зато программировать на С# быстрее и приятнее. :)

Зато программы уродские и тормозные получаются. Парадоксс.


 
Anatoly Podgoretsky ©   (2007-11-01 14:58) [47]

> wendy parkinson  (01.11.2007 14:47:39)  [39]

У тебя проблемы с винчестером, купи побольше.


 
Alkid ©   (2007-11-01 15:00) [48]


> Ага, уже любой пенсионер на свою пенсию и из любой деревни
> может выкачать из инета 30 метров. ;)

А у большинства пенсионеров в деревне вообще компов нет. Что, заря программисты вообще существуют?


> Зато программы уродские и тормозные получаются. Парадоксс.

Это из разряда "мне друг напел"? :)
Грамотно спроектированные решения на C# и выглядят красиво и по скорости исполнения обходят нативный С++ код на вычислительных задачах.


 
homm ©   (2007-11-01 15:04) [49]

> [48] Alkid ©   (01.11.07 15:00)
> и по скорости исполнения обходят нативный С++ код на вычислительных задачах.

Бла-бла-бла.


 
homm ©   (2007-11-01 15:05) [50]

Грамотно спроектированные решения на C# в виде пустой формы стартуют на Селероне500 с 128мб памяти 30 секунд. Куда уж там нативному коду…


 
DrPass ©   (2007-11-01 15:08) [51]


> Грамотно спроектированные решения на C# и выглядят красиво
> и по скорости исполнения обходят нативный С++ код на вычислительных
> задачах

Только следует уточнить - нативный С++ код, написанный дятлом


 
Anatoly Podgoretsky ©   (2007-11-01 15:13) [52]

> Alkid  (01.11.2007 14:57:45)  [45]

Наверно для того и ходят, что бы не развинчивали.


 
Anatoly Podgoretsky ©   (2007-11-01 15:14) [53]

> homm  (01.11.2007 14:57:46)  [46]

Посмотри тесты быстродействия на RSDN и удивись.


 
Alkid ©   (2007-11-01 15:15) [54]


> Бла-бла-бла.

Потрясающий по аргументированности ответ, однако :)
Постараюсь быть более аргументированным:
http://www.grimes.demon.co.uk/dotnet/man_unman.htm


 
Alkid ©   (2007-11-01 15:17) [55]


> Наверно для того и ходят, что бы не развинчивали.

Ну, столь глубоких мотивов выяснить не могу :)


 
Palladin ©   (2007-11-01 15:27) [56]


> wendy parkinson   (01.11.07 14:31) [33]

хм... Наличие виртуальных конструкоторов и VCL делает Delphi однозначно лучше среди языков своего класса


 
Alkid ©   (2007-11-01 15:32) [57]


> хм... Наличие виртуальных конструкоторов и VCL делает Delphi
> однозначно лучше среди языков своего класса

VCL - это библиотека, она к языку не очень относится. А вот виртуальные конструкторы - это 5!


 
homm ©   (2007-11-01 15:35) [58]

> [54] Alkid ©   (01.11.07 15:15)
> Постараюсь быть более аргументированным:
> http://www.grimes.demon.co.uk/dotnet/man_unman.htm

Ну и? Смотрим на столбец Optimized For Speed, и видим что результат в пределах погрешности. Смотрим на количество съеденой опреативы этими процессами, и сразу видим аутсайдера.


 
Palladin ©   (2007-11-01 15:38) [59]


> Alkid ©   (01.11.07 15:32) [57]

это я приплел, что бы MFC"ой не хвастались...


 
Alkid ©   (2007-11-01 15:41) [60]


> Ну и? Смотрим на столбец Optimized For Speed, и видим что
> результат в пределах погрешности. Смотрим на количество
> съеденой опреативы этими процессами, и сразу видим аутсайдера.

Ну, строго говря разница там примерно на прядок больше статистической погрешности :) А про количество съеденной памяти там вообще речи нет, и я про неё не говорил :)

Это первая ссылка на эту тему, если ещё найду - подброшу. Я не пытаюсь отрицать очевидного. Например того, что .NET приложения прожорливее по памяти. Но хочу показать, что утвержденияо "тормознутости" .NET как правило голословны.

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


 
Alkid ©   (2007-11-01 15:43) [61]


> это я приплел, что бы MFC"ой не хвастались...

MFC-ой хватались?! :) Не смеши меня. Такого монстра, как MFC я давно не видел. ИМХО одна из весьма неудачных классовых бибилиотек.

С другой стороны, если "говорим Делфьи, подразумеваем VCL", то в С++ такого нет. Хорошо это или плохо, но для С++ есть куча конкурирующих библиотек разного назначения.


 
homm ©   (2007-11-01 15:45) [62]

> [60] Alkid ©   (01.11.07 15:41)
> Но хочу показать, что утвержденияо "тормознутости" .NET
> как правило голословны.

Ага? [50]


 
homm ©   (2007-11-01 15:46) [63]

> [61] Alkid ©   (01.11.07 15:43)
> С другой стороны, если "говорим Делфьи, подразумеваем VCL",

Кто как.


 
homm ©   (2007-11-01 15:49) [64]

> [60] Alkid ©   (01.11.07 15:41)
> Ну, строго говря разница там примерно на прядок больше статистической
> погрешности :)

Ты меня не заставишь поверить в то, что в виндовс статистическая погрешность может быть меньше хотя-бы 10мс.


 
Alkid ©   (2007-11-01 15:52) [65]


> Ага? [50]

И что из этого следует? Ты сам понимаешь, что этот пример показывает нам, что .NET Run-Time инициализируется медленее, чем Run-Time нативных приложений, но это ничего не говорит о скорости выполенния самих программ.


 
Alkid ©   (2007-11-01 15:57) [66]


> Ты меня не заставишь поверить в то, что в виндовс статистическая
> погрешность может быть меньше хотя-бы 10мс.

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


 
homm ©   (2007-11-01 15:57) [67]

> [65] Alkid ©   (01.11.07 15:52)
> но это ничего не говорит о скорости выполенния самих программ.

Что в скорость выполнения самих программ не входит скорость выволнения их инициализации?
Чем больше программа хавает оперативы, тем она медленее будет исполнятся на компьютере с небольшим ее количеством, и еше другим программам мешается.


 
umbra ©   (2007-11-01 15:59) [68]


> это ничего не говорит о скорости выполенния самих программ.

так выполняется же в любом случае нативной код, хоть в .NET, хоть в С++. Поэтому выражение ".NET быстрее нативного кода" бессмысленно.


 
Palladin ©   (2007-11-01 16:01) [69]


>  Такого монстра, как MFC я давно не видел. ИМХО одна из
> весьма неудачных классовых бибилиотек.



> С другой стороны, если "говорим Делфьи, подразумеваем VCL",
>  то в С++ такого нет.


эт точно... но все равно грех VCL не упомянуть... :)


 
Mystic ©   (2007-11-01 16:05) [70]

> Но хочу показать, что утвержденияо "тормознутости" .NET
> как правило голословны.


После такого рода заявлений я решил попробовать C#. Выбрал себе задачу (шахматы, генератор ходов), для которой критична производительность (сила напрямую зависит от количества позиций в секунду). Понеслась.

Итак, как хотелось бы представить себе поле? Поскольку очень хотелось бы, чтобы была допустима запись

using namespace Chess;

Field x = Field.A1;
Bitboard test = x.GetBitboard();

и т. д., то первой мыслью было объявить тип Field не как enum, а как struct, наподобие System.Drawing.Color. Итак


   struct Field
   {
       private int index;

       private Field(int _index)
       {
           index = _index;
       }

       public Field(Field Orig)
       {
           index = Orig.index;
       }

       public static bool operator ==(Field a, Field b)
       {
           return a.index == b.index;
       }

       public static bool operator !=(Field a, Field b)
       {
           return a.index != b.index;
       }

       /* Просят объявить, хотя я его использовать не собираюсь */
       public override bool Equals(object a)
       {
           if (typeof(Field) != a.GetType()) return false;
           return this == (Field)a;
       }

       /* Тоже надо */
       public override int GetHashCode()
       {
           return index.GetHashCode();
       }

       static public Field A1
       {
           /* Оптимизация, потому что return new Field(0) приводит к unboxing */
           get
           {
               Field Data;
               Data.index = 0;
               return Data;
           }
       }

       static public Field B1
       {
           get
           {
               Field Data;
               Data.index = 1;
               return Data;
           }
       }

   }


И использовал его я, как и хотел, так:


       static int Test()
       {
           Chess.Field Test = Chess.Field.A1;
           if (Test == Chess.Field.A1)
               return 0;
           else if (Test == Chess.Field.B1)
               return 1;
           return -1;
       }


Скомпилировал в релизе, опция Optimize Code стоит. Смотрю что вышло:


;        static int Test()
;        {

00000000  sub         rsp,48h  ; Инициализация фрейма стека

00000004  mov         r8d,4    
0000000a  xor         edx,edx
0000000c  lea         rcx,[rsp+20h]
00000011  call        FFFFFFFFFF514BA0 ; Вызов не расшифрован

00000016  nop              
00000017  mov         rax,64280013128h
00000021  mov         eax,dword ptr [rax]
00000023  test        eax,eax
00000025  je          000000000000002C
00000027  call        FFFFFFFFFF78DDC0 ; Вероятно обращение к JIT-компилятору

;            Chess.Field Test = Chess.Field.B1;
0000002c  call        FFFFFFFFFFFFFFD8
00000031  mov         dword ptr [rsp+2Ch],eax
00000035  mov         eax,dword ptr [rsp+2Ch]
00000039  mov         dword ptr [rsp+20h],eax

;            if (Test == Chess.Field.A1)
0000003d  mov         eax,dword ptr [rsp+20h]
00000041  mov         dword ptr [rsp+24h],eax
00000045  call        FFFFFFFFFFFFFFD0
0000004a  mov         dword ptr [rsp+30h],eax
0000004e  mov         edx,dword ptr [rsp+30h]
00000052  mov         ecx,dword ptr [rsp+24h]
00000056  call        FFFFFFFFFFFFFFB0
0000005b  mov         byte ptr [rsp+34h],al
0000005f  movzx       eax,byte ptr [rsp+34h]
00000064  test        eax,eax
00000066  je          000000000000006C

;                return 0;
00000068  xor         eax,eax
0000006a  jmp         00000000000000A5

;            else if (Test == Chess.Field.B1)
0000006c  mov         eax,dword ptr [rsp+20h]
00000070  mov         dword ptr [rsp+28h],eax
00000074  call        FFFFFFFFFFFFFFD8
00000079  mov         dword ptr [rsp+38h],eax
0000007d  mov         edx,dword ptr [rsp+38h]
00000081  mov         ecx,dword ptr [rsp+28h]
00000085  call        FFFFFFFFFFFFFFB0
0000008a  mov         byte ptr [rsp+3Ch],al
0000008e  movzx       eax,byte ptr [rsp+3Ch]
00000093  test        eax,eax
00000095  je          000000000000009E

;                return 1;
00000097  mov         eax,1
0000009c  jmp         00000000000000A5

;            return -1;
0000009e  mov         eax,0FFFFFFFFh
000000a3  jmp         00000000000000A5
000000a5  add         rsp,48h
000000a9  rep ret


Остальное не лучше... Вместо нескольких ассемблерных инструкций переливание из пустого в порожнее...


 
Mystic ©   (2007-11-01 16:06) [71]

Может это я не знаю, как писать? Попробовал скомпилировать такой код:


           System.Drawing.Color Color = System.Drawing.Color.Black;
           if (Color == System.Drawing.Color.Black)
               System.Console.WriteLine("Catastrophic execution");


Результат:


;            System.Drawing.Color Color = System.Drawing.Color.Black;
0000005c  lea         rcx,[rsp+40h]
00000061  call        FFFFFFFFF5A8CBF0
00000066  mov         qword ptr [rsp+000000D0h],rax
0000006e  lea         rcx,[rsp+40h]
00000073  mov         rax,qword ptr [rcx]
00000076  mov         qword ptr [rsp+20h],rax
0000007b  mov         rax,qword ptr [rcx+8]
0000007f  mov         qword ptr [rsp+28h],rax
00000084  mov         rax,qword ptr [rcx+10h]
00000088  mov         qword ptr [rsp+30h],rax

;            if (Color == System.Drawing.Color.Black)
0000008d  lea         rcx,[rsp+20h]
00000092  mov         rax,qword ptr [rcx]
00000095  mov         qword ptr [rsp+58h],rax
0000009a  mov         rax,qword ptr [rcx+8]
0000009e  mov         qword ptr [rsp+60h],rax
000000a3  mov         rax,qword ptr [rcx+10h]
000000a7  mov         qword ptr [rsp+68h],rax
000000ac  lea         rcx,[rsp+70h]
000000b1  call        FFFFFFFFF5A8CBF0
000000b6  mov         qword ptr [rsp+000000D8h],rax
000000be  lea         rcx,[rsp+70h]
000000c3  mov         rax,qword ptr [rcx]
000000c6  mov         qword ptr [rsp+000000B0h],rax
000000ce  mov         rax,qword ptr [rcx+8]
000000d2  mov         qword ptr [rsp+000000B8h],rax
000000da  mov         rax,qword ptr [rcx+10h]
000000de  mov         qword ptr [rsp+000000C0h],rax
000000e6  lea         rcx,[rsp+58h]
000000eb  mov         rax,qword ptr [rcx]
000000ee  mov         qword ptr [rsp+00000090h],rax
000000f6  mov         rax,qword ptr [rcx+8]
000000fa  mov         qword ptr [rsp+00000098h],rax
00000102  mov         rax,qword ptr [rcx+10h]
00000106  mov         qword ptr [rsp+000000A0h],rax
0000010e  lea         rdx,[rsp+000000B0h]
00000116  lea         rcx,[rsp+00000090h]
0000011e  call        FFFFFFFFF5A7DEA0
00000123  mov         byte ptr [rsp+000000E0h],al
0000012a  movzx       eax,byte ptr [rsp+000000E0h]
00000132  test        eax,eax
00000134  je          0000000000000148

;                System.Console.WriteLine("Catastrophic execution");
00000136  mov         rcx,12969090h
00000140  mov         rcx,qword ptr [rcx]
00000143  call        FFFFFFFFF81DFAE0


 
Anatoly Podgoretsky ©   (2007-11-01 16:06) [72]

> Alkid  (01.11.2007 15:57:06)  [66]

И статистика, а не разовое выполнение.


 
Mystic ©   (2007-11-01 16:08) [73]

Примерно в том же ключе. Видимо так писать еще рано. Попробовал другой путь --- просто использовать Enum. Тут я решил сразу писать код, используя напрямую работу с типами int, System.UInt64 и т. д. Итак, общая структура


   enum Field
   {
       A1, B1, C1, D1, E1, F1, G1, H1,
       A2, B2, C2, D2, E2, F2, G2, H2,
       A3, B3, C3, D3, E3, F3, G3, H3,
       A4, B4, C4, D4, E4, F4, G4, H4,
       A5, B5, C5, D5, E5, F5, G5, H5,
       A6, B6, C6, D6, E6, F6, G6, H6,
       A7, B7, C7, D7, E7, F7, G7, H7,
       A8, B8, C8, D8, E8, F8, G8, H8
   }

       public static System.UInt64 MakeBitboard(Field A)
       {
           return (System.UInt64)1 << (System.Byte)A;
       }


Итак, в этот раз код получился лучше:


;        static int Test()
;        {
00000000  sub         rsp,48h
00000004  mov         dword ptr [rsp+20h],0
0000000c  mov         qword ptr [rsp+28h],0
00000015  mov         rax,64280013128h
0000001f  mov         eax,dword ptr [rax]
00000021  test        eax,eax
00000023  je          000000000000002A
00000025  call        FFFFFFFFFF78DE00

;            Chess.Field A = Chess.Field.B1;
0000002a  mov         dword ptr [rsp+20h],1

;            System.UInt64 Test = Chess.Engine.MakeBitboard(A);
00000032  mov         ecx,dword ptr [rsp+20h]
00000036  call        FFFFFFFFFFFFFFE0
0000003b  mov         qword ptr [rsp+30h],rax
00000040  mov         rax,qword ptr [rsp+30h]
00000045  mov         qword ptr [rsp+28h],rax

;            if (Test == 0x01)
0000004a  cmp         qword ptr [rsp+28h],1
00000050  jne         0000000000000056

;                return 0;
00000052  xor         eax,eax
00000054  jmp         000000000000006C

;            else if (Test == 0x02)
00000056  cmp         qword ptr [rsp+28h],2
0000005c  jne         0000000000000065

;                return 1;
0000005e  mov         eax,1
00000063  jmp         000000000000006C

;            return -1;
00000065  mov         eax,0FFFFFFFFh
0000006a  jmp         000000000000006C
0000006c  add         rsp,48h
00000070  rep ret    
;        }


и

;        public static System.UInt64 MakeBitboard(Field A)
;        {
00000000  mov         dword ptr [rsp+8],ecx
00000004  sub         rsp,28h
00000008  nop              
00000009  mov         rax,64280013128h
00000013  mov         eax,dword ptr [rax]
00000015  test        eax,eax
00000017  je          000000000000001E
00000019  call        FFFFFFFFFF78DD50

;            return (System.UInt64)1 << (System.Byte)A;
0000001e  movzx       ecx,byte ptr [rsp+30h]
00000023  and         ecx,3Fh
00000026  mov         eax,1
0000002b  shl         rax,cl
0000002e  jmp         0000000000000030
00000030  add         rsp,28h
00000034  rep ret          
;        }


В этот раз много лучше, но все-таки остаются вопросы:
(а) Разве трудно догадаться сделать вызов функции MakeBitboard inline-ом? Или хотя-бы дать возможность его объявить...
(б) Почему не упростить фрейм функции? Если это вызов JIT-компилятора, то почему не делать обращения к нему до инициализации стека и не затирать впоследствие обращение к нему?
(в) Почему не использовать для хранения локальных переменных регистры, коих в ADM64 дочерта?
(г) В чем смысл jmp 0000000000000030 в функции MakeBitboard?
(д) Зачем использовать передачу параметров через регистры, если потом их копировать в стек?


 
Anatoly Podgoretsky ©   (2007-11-01 16:09) [74]

> homm  (01.11.2007 15:57:07)  [67]

Это расплата за ООП, за managed code, за рантайм вынесеный на уровень системы и прочие прелести.
Дельфи в этом плане находится там же. А если какой ни будь Power Buider / Ява и другие продукты с большим рантаймом.


 
Джо ©   (2007-11-01 16:12) [75]

[71] Mystic ©
Ужас. Честно, ужас.


 
homm ©   (2007-11-01 16:14) [76]

> [70] Mystic ©   (01.11.07 16:05)
> Выбрал себе задачу (шахматы, генератор ходов), для которой
> критична производительность (сила напрямую зависит от количества
> позиций в секунду). Понеслась.

Что вышло то по тестам?


 
Джо ©   (2007-11-01 16:18) [77]

> [76] homm ©   (01.11.07 16:14)
> > [70] Mystic ©   (01.11.07 16:05)
> > Выбрал себе задачу (шахматы, генератор ходов), для которой
>
> > критична производительность (сила напрямую зависит от
> количества
> > позиций в секунду). Понеслась.
>
> Что вышло то по тестам?

А какое там может выйти быстродействие, если даже if (Color == System.Drawing.Color.Black) разворачивается в такой ужас?


 
homm ©   (2007-11-01 16:20) [78]

> [77] Джо ©   (01.11.07 16:18)
> А какое там может выйти быстродействие, если даже if (Color
> == System.Drawing.Color.Black) разворачивается в такой ужас?

Есть мнение что это промежуточный асемблер…
Так все-же?


 
Mystic ©   (2007-11-01 16:28) [79]

> homm ©   (01.11.07 16:14) [76]

До тестов я не дошел. Для меня важнее было не сравнить C# с C++, а сравнить мой генератор ходов с другими. К тому же шахматные программы используют хэш позиций, размер которого задается заранее. Например, я задаю в качестве параметра размер кэша в один гигабайт, и если число информации в кэше подходит к этому значению, то устаревшие/боковые позиции из него удаляются. Хорошей идеи как это реализовать в C# я не нашел. Ну и по совокупности C# был признан языком, не адекватным поставленной задачи :)

Есть чистый генератор + парсер PGN на Pure C, если интересно. Могу выслать для ознакомления при условии неразглашения :)


 
Mystic ©   (2007-11-01 16:37) [80]

> Есть мнение что это промежуточный асемблер…

Это мне показал cordbg.exe. Скомпилировано в релизе.



Страницы: 1 2 3 4 5 вся ветка

Текущий архив: 2007.12.09;
Скачать: CL | DM;

Наверх




Память: 0.67 MB
Время: 0.033 c
4-1179699489
DmitrichJ
2007-05-21 02:18
2007.12.09
RichEdit20A. Как взять текст?


6-1175397157
-=Germe$=-
2007-04-01 07:12
2007.12.09
SMTP сервер.


11-1179996237
=BuckLr=
2007-05-24 12:43
2007.12.09
ScrollBars в рантайм


2-1194729603
sdaf
2007-11-11 00:20
2007.12.09
иконки в систем трэй


15-1194939406
TYuD
2007-11-13 10:36
2007.12.09
Не всегда получается отладка dll.