Имя: Пароль:
IT
 
Что быстрее, ООП или процедруные ЯВУ
Ø₽ (Волшебник 08.02.2007 15:26)
0 DGorgoN
 
22.01.07
20:29
сабж..
1 DGorgoN
 
22.01.07
20:30
требую четких аргументированных ответов..
2 DGorgoN
 
22.01.07
20:31
быстрота как в написании программ, так и в скорости их выполнения..
3 у лю 427
 
22.01.07
20:42
сЭр... а не пойти ли вам... на..... за развернутыми ответами...

P.S. делать мне нечего....
4 DGorgoN
 
22.01.07
20:43
(3) вам того-же, по тому-же месту, с той же силой
P.S. Везет..
5 у лю 427
 
22.01.07
20:45
С вас бутылка коньяка за потраченное на вас время...

P.S. сказано - бурундук птица, идите на и ищите крылья...
6 romix
 
модератор
22.01.07
20:45
Если не уходить глубоко в дебри виртуального наследования и COM, то скорость одинаковая.
7 romix
 
модератор
22.01.07
20:47
Кодить в процедурном стиле заметно сложнее/муторнее чем в ООП.
Волшебник не даст соврать относительно PHP. :-)
8 DGorgoN
 
22.01.07
20:54
(6) А если уходить?
9 DGorgoN
 
22.01.07
20:55
(5) Ёжик птица гордая? (надеюсь за Ё претензий не будет :))
С вас 2 бутылки аналогичного, так что взаимозачетом с вас ..
10 romix
 
модератор
22.01.07
21:29
(8) Само по себе (без наворотов0 ООП нисколько не тормозит.
Методы классов - это всего лишь процедуры и функции.
Привязка процедуры к классу производится через искажение (mangling) имен.


   000F3E58 1052 041B ?classCValueListContext@CValueListContext@@2UCRuntimeClass@@B
   001335F0 1053 041C ?flPosting@CDocTransacter@@2HA
   000598F0 1054 041D ?get_set_CurSel@CValueListContext@@IAE?AVCValue@@PAPAV2@@Z
   00134000 1055 041E ?m_StateArray@CDocSetSelectDlg@@2VCSelStateArray@@A
   00133EC8 1056 041F ?m_StateArray@CSbCntSetSelectDlg@@2VCSelStateArray@@A
   00133704 1057 0420 ?m_lParam@CGetDlg@@1JA
   000F0F08 1058 0421 ?messageMap@CBrowseView7@@1UAFX_MSGMAP@@B
   000F1918 1059 0422 ?messageMap@CCalcVarSelDlg@@1UAFX_MSGMAP@@B
   000FC078 1060 0423 ?messageMap@CDocFindDlg@@1UAFX_MSGMAP@@B


Привязка процедуры или функции к объекту - кажется, в регистре ECX.

Так что замедления может не быть вообще.
11 DGorgoN
 
22.01.07
22:27
(10) Опять же рассматривал пример. Есть объект точка. Есть объект линия, он строиться с помощью объекта точка, с треугольником такая-же тема :) Хотя тут полемики много :)
12 DGorgoN
 
22.01.07
22:29
Для меня все стало боле ясно, спасибо, romix..
13 Волшебник
 
модератор
22.01.07
23:02
(10) а как же полиморфизм и позднее связывание?
14 Neco
 
22.01.07
23:33
В конечно итоге все сводится к машинным кодам (х86). На этом уровне пофиг на чем писано ООП или процедуры. Тут главное компилятор чтобы хороший был.
15 edor
 
23.01.07
00:00
(14) нифига. При прочих равных ООП требует больших расходов на оперативную память, для хранения таблиц связывания, всяких там виртуальных методов и прочих конструкторов. При процедурном программировании этого хранить не надо, только соответствие имени процедуры/функции и ее адрес
16 Волшебник
 
модератор
23.01.07
00:41
(14,15) Не спорьте. Всё равно 99% времени процессор ничего не делает, ждёт юзера, память, диск и т.д.
17 edor
 
23.01.07
00:48
(16) Вот-вот, как раз и ждет выборки из таблицы виртуальных методов :)
18 romix
 
23.01.07
01:29
(13) Никто не заставляет юзать динамические типы данных.
Тот же самый код пишется и простыми методами наподобие:

.GetType
.AsString
.AsInteger
.AsBoolean
... и т.д.

Быстрее работает, и код получается более определенный. Например, если я говорю .AsInteger или .AsBoolean, то я точно знаю что я хочу. Можно выдать понятное сообщение об ошибке, если на входе не Integer, а нечто другое. А динамический тип скорее всего проглотит ошибочное значение, и ошибка где-нибудь вылезет в неожиданном месте дальше по коду.

Если я пишу код со статическими типами (явно прописываю все типы), то замедления ООП по сравнению с процедурным стилем нет вообще (возможно этот код даже быстрее, за счет хранения указателя на объект в регистре), и код более надежный (почему - см. выше).

Иногда вариантные (динамические) типы уже встроены в какой-нибудь Microsoft OLE, но по-моему в .NET-е с ними уже распрощались и юзают только в целях совместимости с ранними разработками.
19 dk
 
23.01.07
08:12
Э, а компилируемые или некомпилируемые пофигу?
20 Истина
 
23.01.07
08:36
При сегодняшней доступности двухядерных систем и модулей памяти ИМХО уже плевать на чем писАть. :)
21 DGorgoN
 
23.01.07
08:39
Если у вас идет расчет нейронной сети или моделирование 3Д графики с реальным обсчтом света, то не пофигу..
22 smaharbA
 
23.01.07
08:45
(0) а че это такое ? серьезно...
- Мы в университетах не кончали...(с)
23 DGorgoN
 
23.01.07
08:55
(22) Ну такого я от тебя не ожидал.. Яндекс тоже не изучал?
www.ya.ru в зубы и вперед :)

http://www.math.rsu.ru/smalltalk/obzornew-2.ru.html
http://www.glossary.ru/cgi-bin/gl_sch2.cgi?R1dOh&lqy:
24 smaharbA
 
23.01.07
09:32
(23) не абривиатуры я то знаю, но в чем принципиальная разница не понимаю, хоть убей... :)
25 Mort
 
23.01.07
09:37
(24) ООП совсем другая религия. Кто так не считает, обычно пишет процедурный код юзающий классы.
26 DGorgoN
 
23.01.07
09:41
(24) В этом кстати тоже кроется ошибка, чаще производительости..
27 DGorgoN
 
23.01.07
09:45
(24) Не учитель, на простом языке объяснить не могу, лучше самому месяц покурить, покодить и сам до всего додумаешся..
28 smaharbA
 
23.01.07
09:47
(25) а мне без разницы, классы пользовать просче, но писать их самих маятно...
29 smaharbA
 
23.01.07
09:48
(26) быстрее всего работает "линейный" код, вообще без процедур...
30 DF_Slayer
 
23.01.07
09:49
ООП, как известно появилось позже, чем ЯВУ, с расчетом на большие ресурсы машин. Поэтому логичным кажется вывод, что ООП медленне. Хотя не буду утверждать категорично. Сравнивать скорость разработки не вижу смысла, так как цели разные у этих подходов.
31 DF_Slayer
 
23.01.07
09:50
(29) Это точно :)
32 dk
 
23.01.07
09:50
(29) Но не в разы же, имхо, проигрыш менее 10%
33 DGorgoN
 
23.01.07
10:01
(32) Если тебе дорога каждая итерация процесса, то уже много..
34 dk
 
23.01.07
10:04
(33) Ну и пиши на ассемблере тогда
35 DF_Slayer
 
23.01.07
10:06
(34) Ассемблерные вставки рулят)
36 DGorgoN
 
23.01.07
10:07
(34) ассемблер неэффективен. Эффективна связка обычного си со вставками ассемблера..
37 orefkov
 
23.01.07
10:10
(30)
Да нифига оно не медленнее в работе. Ну, если тебе так хочется, скажем так:
на ООП есть некоторые накладные расходы времени исполнения, но они ничтожно малы по сравнению с собственно исполнением всей программы.
Не является это "бутылочным горлышком".
Опять же если взять программу серьезного уровня, а не "hello world", написанную с применением ООП, не факт, что для реализации ее функционала при процедурном подходе потребуются меньшие накладные расходы.
А передача адреса объекта при вызове методов и таблички виртуальных функций - это тьфу по современным меркам.
38 dk
 
23.01.07
10:12
(36)
0,5%  тоже менее 10%
----
0,5% критично?
39 DGorgoN
 
23.01.07
10:18
(38) 0,5 уже некритично, т.к. на эти 0,5 придеться убить слишком много времени. к тому-же вопрос в (0) был в другом. Юзать ли с++ вмести с с ассемблером..
40 orefkov
 
23.01.07
10:29
(39)
Если профилировка программы показывает на то, что данный участок программы является "бутылочным горлышком", то можно кусочек и на асме переписать.
41 Vozhd
 
23.01.07
10:33
(39) "Объектно-ориентированное программирование придумал я, но я при этом не имел ввиду с++" (с) Алан Кей
42 mergan
 
23.01.07
10:36
что быстрее "поршак" или "беларусь"?
43 Delta911
 
05.02.07
07:57
DF_Slayer
35 - 23.01.07 - 10:06
   (34) Ассемблерные вставки рулят)
  DGorgoN
36 - 23.01.07 - 10:07
   
(34)(34) ассемблер неэффективен. Эффективна связка обычного си со вставками ассемблера..

- IMHO, полемика в самого начала "не слишком" разумна... Самый быстрый  - ассемблер, а он "процедурный"...:)
А вот вставки - а вот совсем не рулят :)))
Все нужно рассматривать в контексте, и только в нем. "Дельфийская" програмка, даже вся сплош состоящая из встроенного ассемблера, раза в 1,5 (минимиум!) уступает по быстродействию аналогичному коду на С++ (Борландовский C++Builder).
А вот что-то улучшить в том же С++ Билдере ассемблерными вставками  на практике - практически невозможно, слишком трудно соревноваться с оптимизирующим компилятором. Хотя тема эта - "преимущество ассемблера и ассемблерных вставок" - очень плодотворна, много книжек пишут :)

   Волшебник
Модератор
16 - 23.01.07 - 00:41
   
(14,15) Не спорьте. Всё равно 99% времени процессор ничего не делает, ждёт юзера, память, диск и т.д.

- наверное поэтому, в России так популярна Дельфи? - в основном делают программки, ожидающие действий пользователя? Есть много других реальных предметных областей, где процессор на все 100% ЗАГРУЖЕН - вот там от Дельфи просто плачут (посмотрите комменты к исходникам в реальных проектах, например реализация хэш-функций, алгоритмов шифрования - паскалевские исходники - все в ассемблере. Как своеобразный итог дискуссии - ...а попробуйте те же функции реализовать на процедурном языке в реальной програмке... :)
44 NS
 
06.02.07
13:35
Не спорте, нет никакого критичного падения быстродействия на Делфи.
В любом случае самые китичные по скорости участки можно написать на Ассемблере.
А в остальном скорость кода выдаваемого комплятором VC++ и Делфями - примерно одинакова. Пишут критичные к скорости программы на Делфе, так-же их пишут и на Си, есть энтузиасты которые умудряются писать код полностью на Асме.
45 Эрвинс
 
06.02.07
17:58
Если кто не помнит....
Delphi обошел и Билдер и Вижуал С++ в 3 раза по скорости обработки строк!
46 romix
 
модератор
06.02.07
18:17
(45) Дельфийские (и вообще паскалевские) строки работают намного быстрее на типичных операциях, т.к. хранят длину строки (не надо ее всякий раз вычислять, чтобы, например, соединить две строки в одну, найти подстроку и т.д.).
Кроме того, в отличие от строк C, они позволяют хранить нулевой символ (с кодом 0). И они намного безопаснее (невозможны ошибки переполнения, типичные для C).
Крис Касперски в книге про оптимизацию приводил табличку сравнения строковых операций - паскалевские намного быстрее.
На C++ паскалевские строки тоже активно юзаются (правда разные фирмы сделали их по разному, а стандарт STL несколько опоздал, но смысл у них - тот же, хранить длину рядом со строкой).
47 romix
 
модератор
06.02.07
18:25
В Дельфях есть полезные операторы Procedure, Function и var, которых почему-то нет в языке C/C++. О том, что
int c; - это объявление переменной, а
int f(){} - это объявление функции - надо догадываться неявно, по расположению крокозябликов (для сложных объявлений понять "кто на ком стоит" не так просто, даже Керниган в своей книге признает этот недостаток C).
Отсюда более низкая скорость освоения языка новичками, и даже в разы меньшая скорость компиляции (в Дельфи компилится влет, в CBuilder - "долго думает").
Ведущим разработчиком компилятора .NET кстати был специалист фирмы Borland (который делал еще первый Турбо-Паскаль).
48 spock
 
06.02.07
18:36
(46)Вот на кой тебе 0x0 в составе строки? И вообще, ты говоришь про char* - это базовый тип.
Касперский вообще недоучка, как прикладной программист может и хорош.
Под паскалевскими строками ты, наверно, имеешь ввиду BSTR (basic string), которые действительно хранят длину строки в начале.

(47)Ну а такая вообще мозг разрывает :)
typedef int (*PF_WDFF)(class CDocSet*, class COperSet*, int, int, class CDocTransacter*, class CValue*, int);
49 Эрвинс
 
06.02.07
18:45
(48) бывает и хуже.... это мелочь :)
50 romix
 
модератор
06.02.07
18:45
(48-1) На кой он Кернигану с Ритчи оказался нужен, я вот этого не понимаю.
(48-2) А что мешало сделать нормально?
51 romix
 
модератор
06.02.07
18:47
(48) Сам ты недоучка, развелись тут блин евреи, возвышать себя за счет других.
52 Ненавижу 1С
 
гуру
06.02.07
18:49
А еще в Delphi есть виртуальные конструкторы, чего нет в С++
и писать точку вместо -> гораздо удобнее

Плохо что нет шаблонов и STL. Нет перегрузки операций.
53 spock
 
06.02.07
18:53
(51)ты меня евреем назвал???? жжесть, срочно требую обоснования.
для сведения, у него нет высшего образования и как сам говорит, что уже, наверно, не будет.
54 Эрвинс
 
06.02.07
18:58
(52) перегрузка есть... только дибильная....
55 romix
 
модератор
06.02.07
19:01
(53) Нет не тебя :-)
Зато высшее образование есть у Буша например...
56 romix
 
модератор
06.02.07
19:02
(54) А есть ли перегрузка в C#?
57 Эрвинс
 
06.02.07
19:04
(56)не знаю...
58 NS
 
06.02.07
19:04
Никак не могу понять - зачем нужна перегрузка в критичных по исполнению кусках кода?
Функцию в качестве параметра передавать можно, и этого достаточно.
Насчет поддержки разных типов строк - Делфи поддерживает и сишный PChar, и свой String

А насче огромного перевеса Си в быстродействии - это не более чем миф.

Насчет ООП - сложные участки писать с использованием ООП хуже по двум причинам
Это и падение быстродействия, и несколько более сложная отладка.

Большинство шахматных программ использует ООП только в некритичных по скорости участках кода.
59 Ненавижу 1С
 
гуру
06.02.07
19:07
(54) интересно, какая такая перегрузка операций есть в Делфи? перегрузи мне операцию + для класса TObject
60 Эрвинс
 
06.02.07
19:08
(58) согласен со всем кроме :
"Насчет ООП - сложные участки писать с использованием ООП хуже по двум причинам
Это и падение быстродействия, и несколько более сложная отладка. "

переборные алгоритмы по своей сути процедурные....

(59) посмотри модуль variant Дельфи 7
61 spock
 
06.02.07
19:09
+51 Из книги "Техника отладки программ без исходных текстов. - СПб.: БХВ-Петербург, 2005. Касперски К."
"Об авторе
Небрежно одетый мыщьх 28 лет, не обращающий ни на мир, ни на тело, в котором живет, и обитающий исключительно в дебрях машинных кодов и зарослях технических спецификаций. Не общителен, ведет замкнутый образ жизни хищного грызуна, практически никогда не покидающего свою норку - разве что на звезды посмотреть или на луну (повыть). Высшего образования нет, а теперь уже и не будет; личная жизнь не сложилась, да и вряд ли сложится, так что единственный способ убить время from dusk till dusker - это полностью отдаться работе." стр 1 последний абзац.
Мне не доставило удовольствия это сюда переписывать.
зы: книги у него не очень (прыгает от темы к теме и нет четкого плана изложения), вот как раз образования не хватает. Больше сходит на статью компьютерного журнала. Но читать всеже стоит! Или must have :)
62 NS
 
06.02.07
19:13
Сами переборные алгоритмы не явлются критичным по скорости участком шахматной прогрммы.
Критичные - Генератор ходов и оценка.
В этих процедурах идет прямое обращение к структурам доски, иначе, если исползовать ООП получается весьма серьзное падение быстродействия.
Речь идет не о падении быстродействии на использовании методов, а о падении быстродействия от использования ПОЛЕЙ и Методов для обращения к данным.
63 romix
 
модератор
06.02.07
19:17
(58) >"Насчет ООП - сложные участки писать с использованием ООП хуже по двум причинам. Это и падение быстродействия, и несколько более сложная отладка".


                 )    
                 \   )  
                 ()  \                           )
                     ()                       )  \
                           .-"""-.            \  ()
                  ____    /  __   `\     __   ()
               .'`  __'. | o/__\o   |   / /|
              /  o /__\o;\  \\//   /_  // /
     ._      _|    \\// |`-.__.-'|\  `;  /
    /  \   .'  \-.____.'|   ||   |/    \/
    `._ '-/             |   ||   '.___./
    .  '-.\_.-'      __.'-._||_.-' _ /
    .`""===(||).___.(||)(||)----'(||)===...__
     `"jgs"`""=====""""========"""====...__  `""==._
                                           `"=.     `"=.
                                               `"=.

64 NS
 
06.02.07
19:20
romix, даказывай о скорости ООП где-ниюудь в другом месте :)
А мне доказывать что прямое обращение к памяти может быть не быстрее чем обращение к данным при помощи ООП не надо.
65 romix
 
модератор
06.02.07
19:21
(64) NS, скажи мне пожалуйста, чем отличается (на уровне ассемблера) вызов функции и вызов метода класса?
Ты пробовал отладчиком проходить вызов?
66 romix
 
модератор
06.02.07
19:25
(62) А понял мысль.
67 NS
 
06.02.07
19:25
(65) Ромикс, ты мне скажи - какой отншение работа с сылками имеет к вызову ФУНКЦИИ?
Тебе про Фому, а ты проерему. Что такое ООП? Каковы принципы ООП? Это использование Классов и Методов ДЛЯ ОБРАЩЕНИЯ К ДАННЫМ в том числе.
Речь идет о том, что использую ООП ты структуры данных будешь представлять в виде КЛассов, и получишь серьезное падение быстродействия на доступе к данным.

А в критичных по скорости участках для обращения к данным, в том числе в структурах - используются прямые ссылки, но никак не используются ни процедуры, ни функции, ни методы Классов.


Теперь о разнице в скороти. ДЛЯ ПРОЦЕДУР и ФУНКЦИЙ можно использовать inline, который не вызывает падения быстродейстия вообще.
68 romix
 
модератор
06.02.07
19:27
Данные можно юзать и по указателю, тогда не будет "серьезного падения быстродействия".
69 romix
 
модератор
06.02.07
19:28
Или я не прав?
70 spock
 
06.02.07
19:29
(67)если в контексте с++, то не факт, что компилятор подставит по inline функцию.
71 NS
 
06.02.07
19:30
(68) Да, по указателю и юзают.
Но - это как раз не ООП :) Ну никак не вяжется с принципами ООП.
Если бы был вызов метода, а внутри работа с указателями - это одно, но дело в ом, что в критичный по скорости участок ты не можешь вставить НИ ОДНОГО вызова метода, а критичные участки обычно очень велики. Оценка - может занимать несколько десятков тысяч строк кода. И ни одного обращения к клссам и методам.
72 Эрвинс
 
06.02.07
19:34
(71) ООП основные плюсы ООП скорость написания кода и легкость чтения И ИСПОЛЬЗОВАНИЕ БОЛЕЕ ПРОГРЕССИВНЫХ ОБЪЕКТОВ...
представьте себе что таблицаЗначений автоматом подхватывает индексы при поиске? это есть в 8.1 и это приимущество ООП
73 Эрвинс
 
06.02.07
19:35
в процедурном языке для этого пришлось бы переписвать слишком много...
а сложными процедурами типа сортировки пользуются люди редко...
74 NS
 
06.02.07
19:39
(72) речь шла о критичных по скорости участках кода, разве не так?
насчет легкости чтения и простоты написания - Я тебе сейчас скажу, что насояка Боярышника очень полезна для здоровья, и вызывает общую легкость организма.
Не вызывает ООП ни лучшей читабельности, ни легкости написания и отладки.


(70) А это нужно всегда проверять. И в Делфи и в Си. Причем inline может уменьшить количество доступных регистров.

(73) Раскажи это тем кто пишет критичные по скорости участки кода. Посмотри сам код сильнейших шахматных программ с открытыми исходниками, и сходи на форумы разработчиков - ООП в шахматных программах вызывает замедлние в три раза и больше.
75 spock
 
06.02.07
19:43
(71)Вариация на свободную тему (вроде не накосячил):
class Some
{
public:
   Some2* m_pSme;

   DoSomething();
   Some() {m_pSme = new Some2;};
   ~Some() {delete m_pSme;};
}

int main(void)
{
   Some* pSome = new Some;
   Some2* pSome2 = pSome->m_pSme;
   pSome->DoSomething();

   delete pSome;
   return 1;
}
Сплошные указатели и кто скажет, что это не ООП :)
76 NS
 
06.02.07
19:45
Some2* pSome2 = pSome->m_pSme;
  pSome->DoSomething();

Два вызова метода, получил жуткое падение быстродействие. И зачем потребовалось тогда испольовать указатели???? :)
77 Эрвинс
 
06.02.07
19:45
(74) я слишком долго юзал в ООП ассемблерные вставки, что бы слушать бред....
шахматные программы это одна сторона....

но часто бывают важны более простые и модифицируемые коды....
78 spock
 
06.02.07
19:47
(76)указатели затем, что создаем объекты не на стеке, а в куче.
79 NS
 
06.02.07
19:49
(77) Да, только как раз ассемблерными вставками особо быстродействие не поднимешь/ роще написать критичный по скорости участок кода просто без использования ООП, на Си либо на Делфи

А вот простота и модифицируемость в критичных по скорости участках - нафиг не нужна.

Когда у тебя заказчик спосит по трехкратное подение скорости в критичном участке, либо спросят почему программа играет на 100 пунков Эло слабее - ты будешь втирать про простоту и модифицируемость? :)
80 NS
 
06.02.07
19:51
(78)  еще одно падение быстродействия. Лучше выделить самостоятельно область памяти (завести массив), и использовать указатели с инкрементом/декрементом в случае необходимости. Это будет значительно бстрее.
81 Эрвинс
 
06.02.07
19:56
(80) согласен :) правда я немного о другом... скорость написания и функционал+ легкость его наращивания почти всегда (в 99% строк кода) важнее скорости...
82 NS
 
06.02.07
19:59
(81) Такс этим я тоже согласен. Я же говорю с самого начала о критичных по скорости участках.
А в шахматной программе - Для ООП места-то и не остается :)
83 spock
 
06.02.07
20:01
(82)Ну прям грудью на амбразуру :)
Если приложение оконное, то простор для ООП (думаю, что даже в консольном место найдется).
84 NS
 
06.02.07
20:04
(83) Шахматные движки - это консльное приложение. Место находится.
В Крафти - который всегда демонстрируется как образец кода, на миллион строк не нашлось места для ООП :) Как раз по причинам связанным с быстродействием.

И ни в одной сильной шахматной программе места для ООП нет. Фриц вообще написан полностью на Асме. ВЕСЬ движок полностью.
85 Эрвинс
 
06.02.07
20:05
(82) нигде... кроме интерфейса :)) кроме того в шахматных прогах часто меняется сама логика работы... и смысла в повторном использовании кода фактически нет...
86 NS
 
06.02.07
20:06
(85) А интерфейс пишут другие разработчики :)
87 Эрвинс
 
06.02.07
20:07
(84) про фрица с полностью ассемблеромм... не верю...
скорей всего сгенерили на языке програмирования, а потом критичные куски переписали руками
88 Эрвинс
 
06.02.07
20:07
(87) ассемблер... он не удобен... слишком большой исходник..
89 NS
 
06.02.07
20:12
(87) А зря не веришь :)
Франс Морш один из старейших разработчиков шахатных программ, до этого работал в Мефисто и Фиделити - и всегда писал полностью на Асме, в течении тридцати лет - только Ассемблер. Дело  том, что в шахматной программе некритичные по скорости участки занимают только один процент кода.

но - например Фрукт написан полностью на СИ, и при не битовом представлении доски  самое критичное это количество обращений к памяти, и тут асм не поможет, поэтому Фрукт несмотря на отсутствие ассемблерных вставок играет на уровне сильнейших программ.

При битовых представлениях ассемблер уже дает заметную прибавку к быстродействию.

Фриц  - Битбоард движок, и практически весь код критичен, поэтому и асм...
90 NS
 
06.02.07
20:14
(88) На самом деле примерно то-же самое по размерам кода.
посмотри форумы шахматных разработчиков - огромные полотна кода на асме выкладывают :)

я на такие подвиги не способен, поэтому использую Мэйл-Бокс представление доски, при котором Вставки не нужны.
91 Эрвинс
 
06.02.07
20:19
(89) согласен, что переносить все то что ты сказал на 1с не правильно?
92 Эрвинс
 
06.02.07
20:20
Анечка Твоя?
93 NS
 
06.02.07
20:22
(91) А тут есть разные мнения. Что, например, ООП нужен только частично - фиксированные объекты. Иначе толпы неподготовленных студентов с использованием ООП намого легче наплодят нечитаемого и не подлежащего поддержке кода, чем с использованием процедурного подхода.

(92) Да, сейчас я выложил еще и пограмму в русские шашки, играющую в силу МС.
Ссылка в этом раздее - соседняя ветка.
94 Эрвинс
 
06.02.07
20:25
(93) тогда вообще не надо довать лазить в конфигуратор...
95 Эрвинс
 
06.02.07
20:27
(93) форсированная, обычная глубина какая?
96 NS
 
06.02.07
20:28
(94) И кто будет тогда писать на 1С?
Проще отказаться от ООП.

На Аксапте с использованием ООП такое вытворяют... Причем судентов искать не надо. В самой поставке разработчики в своей иерархии объектов запутались.
97 NS
 
06.02.07
20:30
(95) В шашки очень большая. За минуту, в миттельшпиле - около 30 полуходов, а там еще и продления... То есть считает жутко далеко.
Шахматная - считает как все. В начальной позиции за 5 минут около 15 полуходов.
98 Эрвинс
 
06.02.07
20:30
(96) тут согласен... на проработку иерархии надо много времени... хотя это окупится... просто у 1с есть преимущества перед стандартным ООП... но УПП показывает, что ООП необходимо... хотя бух показывает обратное...
99 Эрвинс
 
06.02.07
20:32
(97) я дальше 4 полуходов написать не смог... правда это было в 14 лет и на бейсике на МС1502.... :)) зато форсированные до 7 доходило
100 NS
 
06.02.07
20:35
(99) с ФВ и с моими продлениями -в шахматы за 30 полуходов, в шашки около 50-ти :)

4 полухода - это ежели минимакс. даже альфа-бета дает больше. А сейчас используют очень много сокращений, очень хорошие сортировки - в итоге глубины запредлные.
101 Фигня
 
06.02.07
20:35
Холивар. Разница здорово зависит от транслятора. ИМХО на личном сравнении разницы не заметил. Однако, в свое время искал на соурсефорже ХМЛ-парсер попроще с образовательными целями. И наткнулся на вариант реализации как процедурной, так и объектной. В комментариях было написано, что если данные слабо иерархизированы, то лучше объектная версия, а если иерархичность сложная, то лучше процедурная. Разница согласно авторам доходила до 10%. Правда бенчей не было и версия была 0.1.1. Пожалуй, соглашусь с НСом.
102 Эрвинс
 
06.02.07
20:37
(100) 8088 6мегогерц бейсик.... :)))  прямой перебор никакого там минимакса или альфабетты или альфы с окнами
103 NS
 
06.02.07
20:38
(102) Прямой полный перебор - это и есть минимакс :)
104 Эрвинс
 
06.02.07
20:39
(101) 10% это не принципиальная разница.... даже для шахматных прог
105 NS
 
06.02.07
20:39
(104) в шахматных прогах получается не 10%, а 200% :)
В три раза.
106 Эрвинс
 
06.02.07
20:40
(103) при 4 полуходах :))) при 10 да при 8 да... а вот при четырех :))))
107 Эрвинс
 
06.02.07
20:41
(105) так разговор идет о том что преимущество в 10% важно :))
108 NS
 
06.02.07
20:41
(106) Минимакс н может считать на 8 полуходов.
При минимаксе размер дерева равен количеству ходов в позиции в степени - глубина.
40^8 позиций перерубить невозможно.
109 NS
 
06.02.07
20:43
(107) в шахматах 10% это всего 10 пунктов Эло - абслютно некритично.
110 Эрвинс
 
06.02.07
20:45
(108) тогда и применяется оссечение альфа бетта, которое в среднем дает возможность просматривать в 2 раза большую глубину если применять окна (почти альфа и бетта с прошлого прохода) то это позволяет выйграть еще 10% глубины....
повторные позиции это сокращение на сколько?
111 NS
 
06.02.07
20:46
(110) Еще в четыре раза.
112 Эрвинс
 
06.02.07
20:48
(111) хеш для позиций стандартный или каждый свое изобретает?
113 NS
 
06.02.07
20:49
(110) В два раза большая глубина - это предел для всех вариаций Альфа-беты при идеальных сортировках.
Насчет 10% глубины ничего н понял. Такая большая глубина сtйчас достигается за счет отсечений/сокращений. Футилити, LMR, Null-Move. В итоге при минимаксе бренчинг фактор равен 40, при чистой Альфа-Бете - 7, а в играющих программах... 2. То есть перебор на один полуход дальше - в два раза больше времени.
114 NS
 
06.02.07
20:49
(112) Хеш конечно у всех разный. На самом дле всё у всех разное.
115 Эрвинс
 
06.02.07
20:52
смотри....
берется окно то есть альфа не с -бесконечности и бетта +бесконечности, а с немного расширенного окна прошлого прохода...

неплохо... 2 а это с потерей вариантов?
116 Эрвинс
 
06.02.07
20:53
(114) у тебя размер хеш таблицы сколько?
117 NS
 
06.02.07
20:54
(115) Это называется "узкое окно в корне"
Оно при больших глубинах ничего не дает, асейчас вообще используетсяобычноне альфа-бета, а PVS, которому это сужение окна вообще нафиг не сдалось, в нем и так окно всегда (в 99% узлов) нулевой ширины :)
118 NS
 
06.02.07
20:55
(116) Сколько пользователь выберет, столько и будет :)
119 NS
 
06.02.07
20:56
Клавиатура уже совсем сдохла :(
120 Эрвинс
 
06.02.07
21:00
(118) нормальная сколько?
121 NS
 
06.02.07
21:03
(120) 32-64 Мб.
От размеров Хеш памяти мало чего зависит. Удвоение размера дае прибавку всего в 7 пунктов Эло.

Мои и шашечная, и шахматные программы допускают установку любого размера от 32 до 512 мегабайт.
122 Эрвинс
 
06.02.07
21:04
(121) я не в мегах, а в позициях...
123 Эрвинс
 
06.02.07
21:04
позиция сколько там занимает?
124 NS
 
06.02.07
21:05
(123) 128 бит, 16 байт. В мегабайте 65000 позиций.
125 NS
 
06.02.07
21:06
(+124) Из них 64 бита ключ - Зобрист. и 64 бита - данные. Вспомогатльная информация, оценки, лучшиеходы, глубина на которой они были получены.
126 Эрвинс
 
06.02.07
21:08
(125) не проще (и быстрее) работать с байтами? потери на преобразование из битовой формы в байтовую не критичны?
127 NS
 
06.02.07
21:10
(126) Какая разница с чем работать? :)
С байтами, с битами... Время занимает только чтение записи из памяти, и вычисление ключа по позиции.
128 Эрвинс
 
06.02.07
21:12
(127) проблема неуникальности ключа?
129 NS
 
06.02.07
21:13
(128) Какая может быть проблема при 64-битном зобристе?
При современных скоростях с 32 битным ключем проблемы будут, а вот 64 битный дает огромный запас. Коллизии мимальны, на силу не влияют.
130 Эрвинс
 
06.02.07
21:15
"32 битным ключем проблемы будут" не понял
"Коллизии мимальны, на силу не влияют." Офигеть!!!!!!!! вообще какова вероятность коллизии?
131 NS
 
06.02.07
21:19
при 32-битном ключе коллизии будут. И их будет очень много.
Вероятность коллизии - то что возмем оценку или лучший ход не той позиции - несколько на партию. в процентах лень считать. Рассмотрим один раз в дереве не тот ход первым - вообще ерунда. Возмем один раз из миллиарда обращений к хешу неправильную оценк - тоже на силуе не скажется.
132 Эрвинс
 
06.02.07
21:21
(131) это сильно зависит от качества хеша... часто теоретическая вероятность для хешей не похожа на практическую
133 NS
 
06.02.07
21:22
(132) Я тебе говорю про практические цифры, а не расчсчитанные теоритически :)
Торитический предел - абсолютно понятно - одна на 16 миллиардов.
134 NS
 
06.02.07
21:24
(132) При Зобристе - качество Ключа зависит от только от качества генератора СЧ.
А его качество в шахматных программах близко к идеальному (а многие прост используют предварительно рассчитанные значения), поэтому вероятность коллизий всего в несколько раз меньше предельных.
135 romix
 
06.02.07
21:24
(71) NS
"Да, по указателю и юзают.
Но - это как раз не ООП :) Ну никак не вяжется с принципами ООП".

В исходных кодах библиотек Дельфи (которые вполне себе объектно-ориентированные) находится место и указателям, и ассемблерным вставкам.

Отказываться от ООП "потому что это медленно" - это не знать предмет на уровне машинного кода, быть жертвой тупых (непроверенных) домыслов, слухов.
136 NS
 
06.02.07
21:28
(135) Ромикс, твои высказывания меня всегда просто убивают.
Ты хочешь сказать, что ты лучше разбираешься в программировании чем тот-же самый Игорь Коршунов? Автор нескольких программ сильнейших в мире. Чем Хьятт - Легенда Американской компьютерной науки, чем Морш? Они говорят о трехкратном падении скорости от ООП.

Они по твоему "жертвы тупых домыслов"? :)
Ну-ну. Только в отличии от твоих поделок, например Crafty используется как основной тест в SPEC CPU.
137 Эрвинс
 
06.02.07
21:31
2^27 позиций 2^64 вариантов хеша
2^37 вероятность попадания одного
переберется позиций сколько? хеш перезаписываемый?

2^30 позиций просматривается или больше?
138 Эрвинс
 
06.02.07
21:32
(136) можешь добавлять в шахматных программах :)
139 NS
 
06.02.07
21:35
(+136)
Плюс ты абсолютно не умеешь читать ветку. Обращение к методу или Классу - это всегда Call, с сохранением регистров в стеке. Это просто беда, убивающая скорость. Напрочь. Обращение к полю через точку - это расчет, на который кроме времени затраченного на расчет адреса, нужены и доп. регистры проца, которых может и не быть свободных в наличии.
(137) Стндартная скорость около миллиона позиций в секунду. из них две трети - в ФВ, в ФВ не идет обращение к Хешу. Считай 300000 обращений к хешу в секунду.
140 NS
 
06.02.07
21:35
(137) Конечно Хеш перезаписываемый.
141 Эрвинс
 
06.02.07
21:36
2^30 позиций просматривается или больше?
142 Эрвинс
 
06.02.07
21:40
за 10 минут
300000*10*60=18 *10^7=0.18 *10^9=2^27.... позиций

согласен... фактически не серьезно....
один неправильных ход на 1000 000 партий
143 NS
 
06.02.07
21:40
(141) За ход - Немного меньше, за партию - больше. Но расчетная вероятность коллизий (одинаковый ключ разных позиций) даже при идеальном Хеше больше чем 2^(-30)
144 NS
 
06.02.07
21:41
(142) Не неправильный ход, а где-то в глубине взятая неправильная оценка, либо неправильный ПОРЯДОК ХОДОв, который просто вызывает мизерное увеличение размеров дерева.
145 Эрвинс
 
06.02.07
21:42
(143) если в ключе нет дыры... и если по ключу нормальный хеш... колизиихеша (н ключа) редкость? (массив заполняется равномерно?)
146 NS
 
06.02.07
21:42
Я где-то считал вероятность одной коллизий при идеальном 32 битном Хеше при разном количестве просмотренных позиций. Могу поискать ветку.
147 romix
 
06.02.07
21:44
NS тебя научить пользоваться отладчиком SoftICE? Не стесняйся если что... Полезная штука...
148 NS
 
06.02.07
21:46
(145) Адрес в массиве - тоже Зобрист :)
Очень равномерно заполняется... Раньше использовали двухуровнвый хеш (две позиции по одному адресу, и по разным признакам выбирал какую из позиций при совпадении ключа перезатирать), но это не дает прибавки вообще - так что сейчас не заморачиваются.
(147) Ромикс, прекрати нести чушь!!!!
Ты что нписал критичное к быстродействию? Я написал третью по силе Шахматную программу в России, а ты?

Для отладки просматривается получившийся ассемблерный код, и используются Перфомансе мониторы. Профайлеры.
149 NS
 
06.02.07
21:49
Ромикс, извини. Опять грублю - очень хреново себя чувствую, впрочем как всегда в последние пол-года :(
150 Эрвинс
 
06.02.07
21:51
(147) смешно :)))
(148) виртуальные машины и т д... (виртуальное исполнение ассемблерного кода)
хотя новые алгоритмы дают намного более существенный выйгрышь
151 masky
 
06.02.07
21:53
на sql.ru уже давно пришли к выводу что хорошо написанный ООп код и процедурный будут очень похожи. щас ссылку найду.
152 masky
 
06.02.07
21:54
153 NS
 
06.02.07
21:55
(150) В Шахматах важно всё. Но если на духкратном ускорении получаешь всего 70 пунктов прибавки, а написать так криво чтоб получить двухкратное падение скорости практически невозможно, то на изобретении в оценке либо в переборных алгоритмах (на каждом) можно получить и больше сотни пунктов, но сгенерированный код просматривается в любом случае, а профайлеры могут сказать не только о "чистоте" написанного кода в плане быстродействии, но и о количестве вызовов - что очеь важно для перебоных алгоритмов, хотя такие вещи лучше делатьвставкой отладочной информации в код.
(151) Возьми любой битбоард генератор ходов (шахматный), и перепиши на ООП - сравни быстродействие, и скажешь о реультатах :)
Вызовы при ООП будут? Сохранение регистров в стеке будут? Расчет адреса будет?
154 masky
 
06.02.07
21:56
(153) это будет мизер по сравнению с алгоритмами
155 romix
 
06.02.07
21:58
(139) NS
>"Обращение к методу или Классу - это всегда Call, с сохранением регистров в стеке. Это просто беда, убивающая скорость.Напрочь".

"Обращение к методу или Классу" поправлю: -> "обращение к методу класса".
Никто не заставляет обращаться к методам и полям классов в глубоком цикле.
Да и "убивающее снижение быстродействия" - надо проверять, а действительно ли на современных процессорах это так.
156 NS
 
06.02.07
21:59
(152) Сколько докторов Наук участвовало в этом обсуждении? :)
большинство разработчиков шахматных программ - именно доктора наук. :)

(154) Российские конкуренты (ближайшие) отстают от меня на пару десятков пунктов Эло по силе. Прибавка 20% к быстродействию позволила бы им догнать мою программу по силе.

Сильнейшие в мире шахматные программы (за исключением конечно Рыбки) сидят толпой в пределах 10 пунктов Эло силы, они борятся за несколько процентов быстродействия. При ООП в данном случае потери в три раза - это совсем несерьезнно, такая программа никогда не будет лидирующей.
157 Эрвинс
 
06.02.07
21:59
(154) мизер... только что ООП даст там? будет ли 5 человек последовательно наследовать объекты перебора?
нефиг лезь даже не в процедурный (там МНОГО инлайн функций) а в монопроцедурный стиль програмировая с иерархическим подходом
158 NS
 
06.02.07
22:01
(155) Ромикс, почитай ветку. Чего тестировать? ОФ вызывается в листьях дерева. 10000 строк кода в котором не только вызовов быть не должно, и сохранений регистров, а вообще не должно быть ни одного лишнего обращения к памяти, и каждый регистр на счету.
Поэтому обращение к классу, с вычислением Адреса, с использованием доп. регистров, и соответсвенно вытеснением части в память - тоже абсолютно неприемлеммо.
159 masky
 
06.02.07
22:04
помоему произошло небольшое передергивание.
и подмена разработки больших проектов штучной топовой программой
160 NS
 
06.02.07
22:06
Кстати, использовани Точки для получения данных - это еще не ООП. Record есть даже в стандарте Процедурого паскаля. Хотя как я уже говорил - в шахматной программе, в 99% кода не должно быть ни одной точки.

(159) Никакого передегивания не было. Было обсуждение использования ООП в критичных по скорости участках - тех же самых Хеш таблицах, сложной математике, и шахматные программы - это просто один из примеров критичного к скоросикода. Причем тт критичен весь код.
161 masky
 
06.02.07
22:08
еще раз повторяю. если критична каждая микросекунда , там не ООП обсуждать надо. а оптимизацию под конкретный процессор.
162 NS
 
06.02.07
22:10
(161)  а я ещ раз говорю - что потери от использования ООП значительно превышают выигрыш от использования Ассемблера. И использование ассемблера - как раз некритично. Критично только при работе с битовыми данными.

и речь идет не о миллисекундх, а о разнице в проценты либо в разы.
163 NS
 
06.02.07
22:11
А оптимизацию под проц - очень хорошо делают современные компиляторы, причем когда есть стандарт на регистры, то критичнымикак раз становятся обращения к памяти, и использоване регистров, а это компиляторы оптимизировать умеют.

причем разница в коде получаемом при помощи лучшего на данный момент Intel C++ Compiler и компилятора Делфи - минимальна.
164 masky
 
06.02.07
22:13
помоему вы НЕ понимаете. пойдем по вашему пути. попробуйте написать программу работы с базой данных  без ООП. и с ассемблерными вставками в 99% кода.
165 masky
 
06.02.07
22:14
ООП это такой же инструмент как и все остальное. и применять его надо к месту
166 Эрвинс
 
06.02.07
22:17
почуму тут 17?
       if (ot mod 17)=0 then

с++ интел и дельфи разница в скорости поверь мне разы.... правда я проверял на математике
167 NS
 
06.02.07
22:18
(166) Завит какой код писать на Дефи - разницы в разы нет. Многие сильные программы написаны на Делфи.
mod 17 =0 - если находимся на главной диагонали.
168 NS
 
06.02.07
22:19
Блин. Зависит какой код написать на Делфи :)
169 NS
 
06.02.07
22:19
(164) ПРИ ЧЕМ ТУТ БЫЗЫ ДАННЫХ? обсуждается использование ООП в критичных по скорости участках кода.
170 romix
 
06.02.07
22:20
(156) Звание "Доктора наук" и "Легенды Американского Программирования" (присвоенное неизвестно кем) еще не страхует от развесистых домыслов и стереотипов.

(158) NS, ты имхо какие-то ужасы пишешь. Надо проверять. Проверю (на простом примере) отпишусь.
171 NS
 
06.02.07
22:20
(165) Вот именно. А в ветке обсуждается именно использоваие ООП...
ну никак не в базах данных.
172 Эрвинс
 
06.02.07
22:21
массив [ot]=1? не быстрее?
173 NS
 
06.02.07
22:25
(170) Написать тебе простейший код?
Чего пробовать? В цикле присваивание по ссылке сравни с присваиванием через точку. А потом попробуй добавить переменных, так чтоб стало нехватать регистров.
Например
T:=timegettime;
for i:=1 to 10000000 do Begin Inc(Point^);inc(Point) end;
Writeln(TimeGetTime);

Сравни с тем-же самым через точку. И хотя идет обращение к памяти, что самое критичное по скорости - всё равно получишь падение в скорости, причем очень большое.

(172) Если тоже самое проделать с массивом - то будет медленней, но в случае простого цикла компилятор справится.
174 NS
 
06.02.07
22:26
(172) Обращениек памяти!!! Это значительно медленней любой регистровой операции.
175 NS
 
06.02.07
22:27
(172) эта версия еще не вылизана по скорости. После вылизывания будет в два раза быстрее.
176 Эрвинс
 
06.02.07
22:28
(174) не деления... деление исключение
177 Эрвинс
 
06.02.07
22:29
(176) деление помойму тактов 5-10 займет.... даже для инта
178 Эрвинс
 
06.02.07
22:30
чтение из памяти 2-3 такта
179 NS
 
06.02.07
22:31
(177) Я этот кусок еще не вылизывал по скорости. Обращение к памяти - это сначала вычисление адреса как минимум, что в итоге полчается вместе с обращением дольше.
180 NS
 
06.02.07
22:32
В Шашчной программе всё проще. Как и в шахматно критичны по скорости только ОФ (EvalUnit) и генераторы/исполнители кода (GenMoveUnit), но если в шахматной ОФ это 10000 строк кода, то в шашчной знчительно менше. и Шашечную я еще не вылизывал.
181 NS
 
06.02.07
22:35
(177) Нет, Байтовый mod занимает значительно меньше :)
Сейчас протестирую...
182 Эрвинс
 
06.02.07
22:36
cmp [адресс массива+ot],1?


вместо очистки регистров edx,eax и еще какого нибудь и выполнения самой длительной операции?

 for i:=2 to 9 do
   for j:=1 to 4 do
     Begin
       ot:=(i shl 4)xor(j shl 1)xor(i And 1);

почему нумерация не с нуля?
тогда бы
до цикла
ot=63
ot=ot-2
если ot=0 тогда выйтипричем цикл можно развернуть при желании
183 Эрвинс
 
06.02.07
22:42
И вообще проверку главной диаганали просто вынести из цикла!ъ
сделать отдельным циклом, так как она нигде не затрагивается внутри
184 NS
 
06.02.07
22:43
Да, обращение к памяти значительно быстрее (в 20 раз), но я же говорю - еще не вылизывал :)
(183) Это уже потом, пока главное - сами алгоритмы.
185 NS
 
06.02.07
22:46
Только что будет когда начнет нехватать процессорного кеша певого уровня?
А из-за Хеш памяти (считай рандомное обращение к памяти) его не будет никогда...
186 romix
 
06.02.07
22:48
(173) Я не буду это тестить, т.к. в глубокие циклы не надо вызовы ООП втыкать.
В глубоких циклах должен быть асм.
187 NS
 
06.02.07
22:50
(186) Не понял. Опять повторяю - в глубоком цикле практичеки весь код.
и использование ООП обсуждается в критичных по скорости участках.
188 NS
 
06.02.07
22:51
Я уже давал ссылку на исходники Крафти - посмотри там процедуру оценки позиции - поймешь что ООП вообще никаким боком. Но и Ассемблер конечно особо не нужен.
189 Эрвинс
 
06.02.07
22:54
unit EvalUnit;

interface

Function Eval(var Red:Boolean):Integer;
implementation
uses BoardUnit,UnitSQEval;
Var  Score:Integer;
Var i,j,ot,kto:Byte;
kolGL:Byte;
WGL:Boolean;
BGL:Boolean;
KWD:Byte;
KBD:Byte;
ODB,ODW:Byte;
// не будет использоваться bp для вычисления

Function Eval(var Red:Boolean):Integer;
Begin
 Red:=False;
 ODB:=0;
 ODW:=0;
 kolGl:=0;
 Score:=0;
 WGL:=false;
 BGL:=False;
 KBD:=0;
 KWD:=0;

  ot:=18;
  repeat
   if pole[Ot]<>0 then
    Begin
     kolgl:=kolgl+1;
     case kto of
       WD:WGL:=true;
       BD:BGL:=true;
     end;
    end;
  ot:=ot+17;
  until ot<=18+17*8;
190 NS
 
06.02.07
22:56
(182) Если нумерация полей доски с нуля... то как в генераторе ходов будешь проверять выход за пределы? :)
Есть схема 0x88, но она значительно медленней. (Проверяем каждое поле на And 136)

(189)  сейчас ОФ написана только для того чтоб проверить переборные алгоритмы. Она, так-же как и генератор будет переписана с нуля.
191 Эрвинс
 
06.02.07
22:56
зачем поле 16*16? и причем нумерация с 1??? ты теряешь на этом много! кроме того усложняешь алгоритм!
192 NS
 
06.02.07
22:57
(191) Как это нумерация с 1??? нумерация с нуля. Еще раз - как ты будешь проверять выход з пределы доски при генерации ходо?
193 NS
 
06.02.07
22:58
Type Doska=Array[0..255] of Byte;
194 NS
 
06.02.07
22:58
Какой алгоритм усложняю? Оценки?  по доске кроме оценки делается генерация ходов :)
195 Эрвинс
 
06.02.07
23:00
а зачем на проверку границ и поле использовать один и тот же массив? да задачи похожи, но в оценочной фнкции которая вызывается чаще проверка границ не нужна!
196 NS
 
06.02.07
23:01
(195) Не совсем понял. Вроде генерация делается из той-же позиции которую будем оценвиать :))
Я не могу В переборе испльзовать одну позицию, а оценват другую :)
197 Фигня
 
06.02.07
23:02
NS меня убедил. С регистровой структурой х86 жпо. Перейдя с DECовской и Мотороловской почувствовал себя кастрированным:). Действительно масса времени уходит на пересылки. Трансляция классов действительно менее эффективна. Только здесь ИМХО следует учесть операционное окружение. Если написанная прога почти не взаимодействует с ОСью, то практически быстродействие определяется эффективностью транслятора. А если взаимодействие с ОСью плотное, то быстродействие начинает нивелироваться. Как правило, современные ширпотребные приложения ориентированы на человека либо плотное взаимодействие с системой (АПИ той же СУБД к примеру). Посему скорости нивелированы. А если требуется критичность к скорости, то хорошо продуманная процедурная программа уделает объектную на раз. Только проверять сие на "простых" примерах глупо, есть варианты более надежные.
.
ПС В свое время были такие штуки как High C, Watcom C, Zortech C,... , специально ориентированные на высокую оптимизацию кода. Борланда, Микрософта они уделывали только так. Потом пошла Винда и системные вызовы нивелировали все.
.
ППС В качестве оценки можно использовать сгенеренный транслятором ассемблерный код (раньше такое можно было проделать, сейчас не знаю), причем как без оптимизации, так и после. При знании азов ассемблера все сразу видно, хотя бы в первом приближении.
.
ПППС. Опыт разработки систем сбора и обработки данных радио и гидро локации, а также изображений, платформ реализации этак не менее 5.
198 romix
 
06.02.07
23:02
(187) Если у тебя в глубоком цикле весь код - откажись и от процедур.
Скажи "процедуры - это тормоза". "Процедуры - это плохо".
199 NS
 
06.02.07
23:03
(198) Да нет ни у кого в ОФ вызовов процедур!!!! Тормоза это - я же тебе сказал. Процедуры только inline, только если хватает регистров.
200 NS
 
06.02.07
23:04
А если не хватает регистров, и в процедуре достаточно ресурсоемкий код - тогда конечно лучше вызов.
201 Эрвинс
 
06.02.07
23:06
левое движение ((ot and 7*8)=0) and ((ot and 7)=8) что то подобное... одним ифом...
202 Эрвинс
 
06.02.07
23:08
(200) для проверки границ один массив, для фигур другой... то есть при движениях будет 2 проверки... вместо одно зато обе более простые
204 NS
 
06.02.07
23:11
(201) Это и есть 0x88 Делается намного проще if (kuda and 136)=0, только от этого в пользу МайлБокса отказались 10 лет назад. Майбокс с полями по краям доски один из самых быстрых вариантов.
(202) Ты говоришь о списках фигур - это тоже замедляет программу. Исполнять ход нужно тоже очень быстро, а ты замедляешь исполнитель.
205 NS
 
06.02.07
23:12
(203) Не знаю маленьких образцов. В шахматном программировании примеры идального, вылизанного кода это Крафти и Фрукт. Фрукт не проще для чтения,
206 Эрвинс
 
06.02.07
23:14
(204) нет...

массив поле [16*16] считается как у тебя хранит только проверку на поле и границу
массив фигуры[8*8]  хранит фигуры
как вариант можно сделать первый массив 8*8 только границу сделать внутренней...
207 NS
 
06.02.07
23:16
(206) Еще раз - а исполнять ход по двум массивам как будешь? В два с лишним раза медленней?
Есть вариант - один масси на 45 элемнтов, ноя всё-равно генератор буду перписывать. Но тесты показывают, что и в шашках и в шахматах - формат доски большого значения не иеет. То есть размер границ и разме массива.
208 Эрвинс
 
06.02.07
23:18
(27) нет не медленне, у тебя это в допроверках неявно сделано, у меня явно...
я думаю даже быстрее
209 Эрвинс
 
06.02.07
23:19
(207) согласен, размер не имеет значения имееет значение простота конструкций доступа
210 MMF
 
06.02.07
23:19
(203) У меня пример попроще - работа с растровыми изображениями, ООП - каждую точку представим в виде объекта (координаты, цвет, методы инверсии, установки цвета и т.д., все наглядно и удобно), все изображение - список объектов-точек. Инвертирование цвета или даже простейшая заливка сколько времени в этом случае займет? И сколько вся куча объектов сожрет памяти? И какая будет фрагментация памяти при выделении массы мелких объектов и прочия...
211 Эрвинс
 
06.02.07
23:20
на мой взгляд при движениях я не проигрываю, зато выигрываю в целевой функции
212 NS
 
06.02.07
23:21
(208) Не могут все ошибаться :) и все тесты врать :). В проверке в МайлБоксе - совмещается проверка выхода за пределы доски с проверкой наличия материала на поле. в 0x88 - лишняя проверка для КАЖДОГО поля.
(211) Исполнний и отмен хода - больше чем в два раза больше оценок. :)
Съели три шашки - Нужно затереть поле откуда пошли, записать куда, снять шашки соперника с доски... и это по двум доскам. Пото одна оцнка, и отмена хода - опять в два раза больше объем вычислений :)
213 Эрвинс
 
06.02.07
23:21
(210) а знаешь можно объектами представить и каждую ячейку памяти и регистры процесоора и нейроны твоего мозга... вот если бы они были объектами то думал бы ты лучше? или так и  остался бы...
214 Эрвинс
 
06.02.07
23:22
(212) по массиву поле нет вообще движений!!!!
215 NS
 
06.02.07
23:24
(210) Заливка на стеке - 10 стро кода. Пример есть в моем Xonix-е, хотя я его бухой писал, не помню что вытворил с заливкой.
(214)То есть мы сделали ход, а на доске ниего не поменялось? Ответ соперика генерируем из позиции без сдланного хода? :)
216 MMF
 
06.02.07
23:24
(213) эк ты меня, тайгу дремучую :-( пойду возьму почитаю Мурзилку и не буду больше встревать в разговор умного дяденьки
217 Эрвинс
 
06.02.07
23:25
если не брать дамок, то каково колво проверок будет по отношению к колво оценочных функций?
218 romix
 
06.02.07
23:26
(199) NS а ничего что в сабже - обсуждение "что быстрее ООП или процедурные ЯВУ"?
А ты подменяешь его обсуждением что быстрее ООП или код "вообще без процедур" (как у тебя в шахматах).

Так вот, если обсуждать сабж, то процедуры (именно процедуры, инлайн предлагаю не рассматривать т.к. фактически это разновидность макроса) и вызовы методов класса чем отличаются, ты в курсе?
219 NS
 
06.02.07
23:26
(217) Количество исполнений хода в полтора больше чем количество оценок, столько-же сколько исполнений отмен хода. Есть схемы с двойным представлением доски, но только в одном случае - одно из прдставлений битовое.
220 Эрвинс
 
06.02.07
23:26
(215) движение осуществляются по массиву фигур....
221 NS
 
06.02.07
23:27
(218) ничем. Я в курсе.
(220) Не понял - если в памяти две доки, то после хода должны изменять обе.
222 Эрвинс
 
06.02.07
23:27
(217) битовое представление не эффективно... оно значительно замедляет работу... эффективно только байтовое
224 romix
 
06.02.07
23:31
(221) Я выиграл? :-)
225 Эрвинс
 
06.02.07
23:32
первая

********
*      *
*      *
*      *
*      *
*      *
*      *
********
используется только для проверки границ! (аналог битбокса)
вторая
с фигурами... за счет меньшего колва ифов этот вариант быстрее...
кстати ифы часто даже тормозят сильнее деления и обращения к памяти
226 NS
 
06.02.07
23:33
(222) :) :) :)
Во сказанул...
Чтоб проверить наличие взятий в шашках пр байтовом представлении сколько нужно оперций? :) А при битовом? Три? В шахматах в конце ФВ. Генераця только взятий. Знаешь во сколько раз битовое быстрее по скорости? Поверка на шах... и т.д.
Битовое представление самое быстрое, но самое трудоемкое по написанию.

(224) Мы же другое обсуждали.

(225) Второй вариант доски после хода нужно тоже обновлять? не так-ли?
В процедре оценки очень мало if-ов.
227 NS
 
06.02.07
23:35
Доска 8x8 В шашках шашки на 32 полях - как будешь проверять в цикле поле на доске или нет? ifами по 64 полям? А у меня что? :) Сколько Ифов при вычислении адресов 32 полей?
228 NS
 
06.02.07
23:37
Мы сейчас отталкиваемся от этого кода -
for i:=2 to 9 do
   for j:=1 to 4 do
     Begin
       ot:=(i shl 4)xor(j shl 1)xor(i And 1);
Сколько мы выиграем представлением 8x8, и сколько отеряем на исполнителе/отмене?
229 Эрвинс
 
06.02.07
23:38
(226) слишком мног :) от многих можно избавится ассемблером... только надо смотреть процент неудачных переходов
в битовом нужны сдвиги... и переход на нужную строку я так понимаю выбираю число гружу в память и сдвигаю на нужное число бит? при байтовом сранении одно сложение и одна загрузка в память... операций меньше...
230 Эрвинс
 
06.02.07
23:39
or i:=2 to 9 do
  for j:=1 to 4 do
    Begin
      ot:=(i shl 4)xor(j shl 1)xor(i And 1);

заменить на
ot:=0;
repeat
.....
inc(ot,2);
until ot<=63;
231 NS
 
06.02.07
23:41
(229) Ты не понял. При битовом представлении доски в шашках - вся доска в двух 32 битных числах!!! И не надо проверять 32 поля в памяти, и от каждого бежать в четырех направлениях.
у меня тут наверно так как два вложенных цикла - около 32 сравнений.
Но цикл - занимает намного меньшевремени, чем проверка поля!!! Это я тестировал.

(230) попробуй, ты не по тем полям побежишь.
Там через строчку на доске - четные и нечетные :)
Если добавлять представлени - то как раз массив на 32 элемента, и просто бежать по нему.
232 NS
 
06.02.07
23:43
что точно нужно сделать - циклы местами поменять. длинный внутри.
233 Эрвинс
 
06.02.07
23:46
:) битовое представление это круто... это занимат мало места и т д...
но проц работает с байтами (когда их не много) быстрее!!! как ты получишь доступ к биту? командой BITC? она медленная... сдигом и сравнением? это дополннительное условие что грузить...
234 Эрвинс
 
06.02.07
23:49
(231) тогда просто развернуть цикл :) и получить 32 почти одинаковых блока
235 Эрвинс
 
06.02.07
23:49
твой код по любому влезит в 64К так что разворачивание без ифов это плюс
236 NS
 
06.02.07
23:50
(233)  Могу дать ссылку как работают с битами...
Несколько битовых операций наверно быстрее чем 100 байтовых причем с обращением к памяти? :)
Битовые генераторы взятий быстрее в... ДЕСЯТЬ РАЗ!!!
проверка на взятия одной фигуры - одно обращение к памяти, причем без сдвигов. Сдвиги нужны только если нет списков фигур, и нужно найи наши фигуры на доске.
Но сдвиг так-же возможен не по одному биту, а сразу до следующей фигуры.
237 NS
 
06.02.07
23:50
(235) Так тоже делают, но очень тяжело потом править код.
238 NS
 
06.02.07
23:51
Я имею в виду - вообще прописать в коде последовательный доступ к 32 полям. к каждому полю отдельной строкой кода.
239 Эрвинс
 
06.02.07
23:52
сдвиг shr shl? или ты под сдвигом понимаешь другое?
240 Эрвинс
 
06.02.07
23:55
(237) а макросом сделать и потом пере копировать макрос?
241 NS
 
06.02.07
23:57
(239) Сдвиг это shl shr...
Но всё не так плохо. Например что делает такой код -


Это кусок битбоард генератора (чужого) с моими комментариями - посмотри код :)
Это шахматная проверка взятий.


Бит боард генератор есть в исходниках Crafty. Это точно лучшее....
По поводу кода -
procedure GetKills(var rec:TBitRec; squareN:integer; var moves:TBitBoard);
var X,Y,index,N:integer;
line,my,leftBits,rightBits:byte;
begin
with rec do
begin
index:=toIndex[squareN];
X:=index and 7; Y:=index shr 3;
my:=byte(1) shl X;
line:=board.bc8[Y] and not(my) and maskY[index];
// почему сразу при формировании maskY не сделано and not(my)?
// И зачем лишний раз обращаться к массиву при генерации ходов ладьи?
// maskY нужен только для слона
rightBits:=line and (my xor (my-1));
// в данном случае line and (my-1) даст тот же самый результат.
leftBits:=line and not rightBits;
// почему "and not", а не просто "xor"?
// в данном случае дает тот-же результат.
if leftBits<>0 then
begin
N:=fromIndex[ByteFirstBitNumber[leftBits and -leftBits]+(Y shl 3)];
// почему не сделан массив ByteFirstBitNumber на 256 элементов?
// не пришлось бы делать leftBits and -leftBits
with moves do
bc8[N shr 3]:=bc8[N shr 3] or (byte(1) shl (N and 7));
end;
if rightBits<>0 then
begin
rightBits:=ByteRotate[rightBits];
// не проще ли вместо двух обращений к массивам было добавить
// массив ByteLastBitNumber на 256 элементов?
N:=fromIndex[ByteFirstBitNumber[rightBits and -rightBits]+(Y shl 3)];
// то же самое, что и раньше -
// от rightBits and -rightBits не
// станет читабельней тест
// а выпендриваются обычно студенты-самоучки...
with moves do
bc8[N shr 3]:=bc8[N shr 3] or (byte(1) shl (N and 7));
end;
end;
end;
//И это процедура которая должна быть оптимизирована по быстродействию....

(240) И так делают.
242 Эрвинс
 
06.02.07
23:58
проверка в битовом как test и установка снятие как or и and? не быстрее это байтов :( не быстрее.... скорей всего также...
243 NS
 
07.02.07
00:01
(242) Не спорь. Это в 10 раз быстрее. Генерация взятий одного слона - это 14 обращений к памяти с проверками!!! Битовая генерация - это несколько операций в регистре.
244 NS
 
07.02.07
00:04
Не битовый - по каждому из четырех направлений.
Kuda:=ot+17;
While Pole[kuda]=0 Kuda:=kuda+17;
if pole[kuda]<0 then

Эт не битовый, и так по каждому из четырех направлений, а теперь сравни с битовым - четремя операциями проверяем возможность взятия по целой диагонали сразу.
245 Эрвинс
 
07.02.07
00:07
(244) в битовом диагонали хранятся отдельно от вертикалей?
246 Эрвинс
 
07.02.07
00:09
при движении в каждую диаганаль надо прописывать отдельно?
то есть приписать движение в 2 диагонали вертикаль и горизонталь?
247 NS
 
07.02.07
00:11
246 в битовом наличие всех фигур соперника хранятся в одном 64 битном числе.
Есть два варианта. первый - простые матрицы - в одном числе.
Второй, более быстрый - в двух числах - одно для вертикалей горизонталей, второе для диагоналей - повернутая матрица.
(246) Для генерации в битовом представлении - вместо бега по четырем направлениям, сразу получаем по диагонали число с битами по двум направлениям на местах фигур соперника. То есть нужно это сделать два раза - по двум диагонялям. Тоже самое с ладьей. Только вертикали/горизонтали.
У ферзя - вместо бега по восьми направлениям. Нужно сделать четыре очень быстрых поверки.
248 NS
 
07.02.07
00:13
index:=toIndex[squareN];
X:=index and 7; Y:=index shr 3;
my:=byte(1) shl X;
line:=board.bc8[Y] and not(my) and maskY[index];
rightBits:=line and (my xor (my-1));
leftBits:=line and not rightBits;
if leftBits<>0 then
Этот код получил для ладьи фигуры под боем сразу по двум направлениям :)
Сравни с байтовым представлением, и это еще и кривой код - возможно написать значительно лучше.
249 Эрвинс
 
07.02.07
00:16
переходи на 64 бита :)
250 NS
 
07.02.07
00:19
(249) Битбоарды дают выигрыш и на 32 битах, но тут трудоемксть написания возрасает настолько, что нет смысла заморачиваться, а выигрыш не очень велик, так как терячем на скорости генерации простых ходов.

сейчас - уже все переходят на битбоарды, так как кругом 64 битный процы. Считается что в целом в шахматной программе выигрыш в быстродйствии наБитБордах в 1.6 раза. 40 пунктов Эло прибавки.
251 Эрвинс
 
07.02.07
00:21
(250) там и регистров не 6(те что для общего использования) а 14 (ESP, EBP не считаю их компилятор для генерации не испоользует)
252 NS
 
07.02.07
00:26
(251) Регистров хватает для генерации и на 32 битах.
А битбоарды лучше писать на Асме - я набрал толмудов по Асму, представляю как голову поломаю с генератором, а потом еще гемор Оценку на битбоардах писать - в шахматах совсем тяжко. В шашках проще. Например наличие Дамки на главной -диагонали - ОДНОЙ операций!!!
253 Эрвинс
 
07.02.07
00:29
(252) наивный.... регистров никогда не хватает :))
254 Эрвинс
 
07.02.07
00:30
просто вынеси из оценочной функции определение переменных и получи 5% выигрыша в скорости :)
255 NS
 
07.02.07
00:33
(253) В генераторе как раз хватает :) если он не очень заморочный.
Я свой шахматный - смотрел Ассемблерный код - ни одной переменной в памяти - всё в регистрах.
(254) 5% совсем не критично. Можно не вынести определения, а просто сделать её СТАТИЧНОЙ!!! Она же не рекурсивная :)
256 Эрвинс
 
07.02.07
00:35
(255) в паскале? и статичной? КАК?
257 Эрвинс
 
07.02.07
00:36
5% бесплатной производительности :)) я потому, что это легко
259 Эрвинс
 
07.02.07
00:39
и сделай выравнивание этих массивов на 256байт
260 NS
 
07.02.07
00:58
(259) Выравнивание стоит в парамтрах компилятора.
Насчет статичности - меня клинит. Нужно пробовать и смотреть ассемблерный код, Вроде в Делфи оптимизирующий компилятор сам понимает, и делает нерекурсивные процедуры сатичными.
261 NS
 
07.02.07
01:08
О гад - не делает статичными. :(
262 NS
 
07.02.07
02:33
Кстати, самый лучший Тест.
Для проверки правильности генератора - perft тест, он же используется для проверки быстродействия связки Генератор/исполнитель хода.
По этому показателю в шахматах - у меня генератор по скорости на уровне сильнейших программ (во всем генераторе ни одной переменной в памяти), в шашках, пока не оптимизирован - в 2.5 раза медленней чем у Каллисто.
Оценку по скорости можно сравнивать по конечному NPS, но ввиду того что всё зависит от мощности оценки, то сравнивать достаточно тяжело. Но известна максимальная скорость на простейшей оценке. В шахматах на Athlon64 2000 мгц это около 2 mNPS, но тут скорость уже зависит от переборных алгоритмов. Чем лучше бренчинг фактор (чем лучше переборные алгоритмы) Тем видимая скорость меньше.
263 Delta911
 
07.02.07
06:55
...ну, понеслись ноги в рай, а душа в милицию...
Как только возникает вопрос типа "кто страшнее - слон или кит, дайте аргументированных ответов", сразу бурное аргументированное обсуждение :) Эту бы аргументированную энергию - да на мирные рельсы, куда нить в сторону 1Сы...

NS
Ведущий
44 - 06.02.07 - 13:35
   Не спорте, нет никакого критичного падения быстродействия на Делфи.
В любом случае самые китичные по скорости участки можно написать на Ассемблере.
А в остальном скорость кода выдаваемого комплятором VC++ и Делфями - примерно одинакова. Пишут критичные к скорости программы на Делфе, так-же их пишут и на Си, есть энтузиасты которые умудряются писать код полностью на Асме.

- я не спорю, я просто знаю. Зачем спорить о том, что можно измерить? Кто не может(не умеет), тот будет спорить.
Ну возьмите да сами посмотрите (...ну ничего ж сложного то нет...) - ...да хоть исходники "библиотеки хэш функции" некоего Кабана - у него и сайт так называется (кабан нет кажется, он из Ритлаб) - пишет только на дельПфи, код - практически полностью на ассемблере - ну не просто же так?! Ну и комменты есть - написано буковками  - почему ассемблер... :) Возьмите эту библиотеку - там даже откомпиленный тест есть - засеките время. Я Вам пришлю аналогичные функции - только написанные на С++ (Билдер) - БЕЗ ассемблера. Быстродействие  - в 1,4-1,5 раза(!) - выше. Сделайте на Дельфи код быстрее моего на С++ - будет Вам шоколадка, и не маленькая  - договоримся. Код MVC - быстрее в среднем, чем код Билдера  - на 5-10%. Это тоже реальные цифры, реальных программ - а не с потолка. Консольные программы - здесь MVC вне конкуренции. Не нужно судить о быстродействии по GUI - и Дельфи, и С++ Билдер использует одну и ту же VCL :)))

"А насче огромного перевеса Си в быстродействии - это не более чем миф"
- вот этим мифом я и занимаюсь :))) Живет зараза, миф на компьютере - что только не делал  - целая мифология, блин... Если 1,5 увеличение быстродействия  - всего лишь миф, то хрен с ним - мну такой миф очень даже устраивает :)

   Эрвинс
45 - 06.02.07 - 17:58
   
Если кто не помнит....
Delphi обошел и Билдер и Вижуал С++ в 3 раза по скорости обработки строк!
   romix
Модератор
46 - 06.02.07 - 18:17
   
(45) Дельфийские (и вообще паскалевские) строки работают намного быстрее на типичных операциях, т.к. хранят длину строки (не надо ее всякий раз вычислять, чтобы, например, соединить две строки в одну, найти подстроку и т.д.).

- да просто бальзам на душу... "Дельфийские" строки - энто какие? НЕ AnsiString  ли часом?! Ни разу в Билдере не встречал ;) что они длину хранят - единственно, почему то индекс у них нужно с 1 использовать... Мдее... Эксперты однако. Почему бы всем, кто хочет говорить (пусть даже и на такую тему) - не привести мааленькие, но примерчики кода? И делов-то...

P.S. Будьте проще,конкретнее  - и люди перестанут с вами общаться. (Один знакомый сказал)
264 DF_Slayer
 
07.02.07
06:57
(263) Хорошо сказал... Поддерживаю.
265 Delta911
 
07.02.07
06:58
DF_Slayer

- спасибо.

:)
266 Elkmor
 
07.02.07
07:49
(0) Читал Страуструпа (создателя языка С++) что виртуальные функции ООП в типичной программе занимают значительно меньше одного процента времени, где-то 0,01%.

(263) Делфевые строки нумеруются с 1 потому что по привычке с Паскалем, в Паскале в ячейке с адресом 0 хранилась длина строки (максимальная длина строки была из-за этого 255).

Что быстрее Делфи или С++ зависит целиком и полностью от конкретного компилятора, а никак не от самого языка. В С++ также возможны разные библиотеки обработки строк, равно как и разные способы хранения строк (стэк/динамика) и разные форматы строк (кончающиеся на 0, делфи-стиль) поэтому замер romix не особо впечатляет ;).
267 romix
 
модератор
07.02.07
13:13
(263) "Я Вам пришлю аналогичные функции - только написанные на С++ (Билдер) - БЕЗ ассемблера. Быстродействие  - в 1,4-1,5 раза(!) - выше".

Замеры могут зависеть от профилировки под конкретный процессор.
Касперски в своей книге оптимизирует скорость образца кода в десятки раз, используя высокоуровневый язык.

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

Например x:=10;
вряд ли в дельфи транслируется во что-то очень уж отличное от того же кода на C.
Ничего волшебного язык C собой не представляет: фактически, это другое представление ассемблера, как и любой компилирующий язык.
268 NS
 
07.02.07
13:18
"Я Вам пришлю аналогичные функции - только написанные на С++ (Билдер) - БЕЗ ассемблера. Быстродействие  - в 1,4-1,5 раза(!) - выше. Сделайте на Дельфи код быстрее моего на С++ - будет Вам шоколадка, и не маленькая  - договоримся. Код MVC - быстрее в среднем, чем код Билдера  - на 5-10%. Это тоже реальные цифры, реальных программ - а не с потолка."

Эти цифры действительно похожи на реальные, за исключением одного - Билдер генерит код не лучше чем Делфи.

Я встечал много тестов, где авторы на конкретных примерах доказывают что Делфи медленней, только каждый раз оказывается что Делфи они не знают, пишут на нем впервые в жизни, и пытаются передать массив в процедуру в качестве параметра... Не по ссылке, не Var, не указатель, а полностью массив :)

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

В противном случае частенько оказыватся что хороший компилятор с трансляцией справляется лучше, чем горе-оптимизатор.
269 romix
 
модератор
07.02.07
13:18
Так же ничто не мешает написать критичные по скорости куски кода на разволшебном C и поместить их в DLL. И уже юзать откуда угодно, хоть из 1С :-)
270 DGorgoN
 
07.02.07
13:23
А ветка жива еще, слабо до 300? :)))

(269) Или на ассме..
271 NS
 
07.02.07
13:24
(269) А если весь код такой? То С и юзают.
Насчет в чем вред ООП - в том о чем я писал с самого начала. Именно ООП является причиной кода (75)
272 romix
 
модератор
07.02.07
13:26
(271) NS ничего что тебя новички прочитают и проникнутся заботой о вреде ООП?
273 NS
 
07.02.07
13:31
(272) Именно новичкам ООП подход и вреден, есть мнеиячто начинать учить нужно с процедурного подхода, и уже при достаточной подготовлнности перходить на ООП.
Именно новычкам ООП мешает, толкает их к очень неоптимальному и запутанному коду.
274 romix
 
модератор
07.02.07
13:32
(+272) Начнут процедурами все колбасить...
Не все же знают, что вызов методов и вызов процедуры - в машинном коде почти не отличимы.
А доступ к данным через поля класса ничем не лучше и не хуже, чем через поля структуры...
275 romix
 
модератор
07.02.07
13:36
(273) В чем же отличие процедуры от метода? Прошу источник (или внятное обоснование) сей развесистой мысли.
276 NS
 
07.02.07
13:37
Нет, с процедурным подходом будут обращаться к данным нпрямую, не использую для извлечения данных функций и методов. Просто присваивать оператором присваиваия. Посмотри код в (75) При процедурном подходе для работы с данными никому бы в голову не пришло использовать процедуру. Если процедуру то inline, либо Шаблоны/макросы.
277 NS
 
07.02.07
13:38
(275) Я тебе уже сказал - для простой операции присваивания никто не будет делать вызов процедуры, а методы используют вовсю. Вот в чем отличие.

Виртуальные Деструкторы. Ты всегда можешь понять что присходит при уничтожении объекта при сложной иерархии?
278 romix
 
модератор
07.02.07
14:58
(276) Не знаю кому и чего приходит в голову (или в другое место), но метод класса и процедура по сути - одно и то же, и вызывать их можно одинаково. Искать там вредоносность или медленность - это надо иметь предубеждение (вероятно, навеянное чьими-то развесистыми глюками).

К примеру, класс для работы с XML первоначально был у меня набором процедур и переменных, потом я просто поместил их в класс. По сути ничего не изменилось, но пользоваться стало намного удобнее. Например, я могу без затруднений работать одновременно с несколькими XML файлами, а в случае с процедурами мне пришлось бы лепить немного несуразные вещи типа массива структур, с доступом через числовые идентификаторы (очень удобно, не правда ли?). Обращение через точку более наглядно (код более читабельный, его легче воспринимать).

Ничто не мешает работать с данными напрямую (например, через указатель). Однако часто не рекомендуют это делать по причине легкости взлома таких программ, а также возможности накосячить, испортить данные из-за ошибки. Если же (например, в шахматах) это несущественно, а важна скорость - да кто же против, обращайся с данными напрямую (через указатель или ассемблерные вставки), ООП от этого процедурным стилем не станет.
279 NS
 
07.02.07
15:02
Мы опять говорим о разных вещах. ООП позволяет писать плохой, неэффективный и запутанный код, и провоцирует именно такой код. Я не спорю что по сути вызов метода и вызов прцедуры это практически одно и тоже, но процедурный подход намного меньше провоцирует на плохой код, и дает меньше возможностй для такого кода.
Поэтому и говорю о том, что начинать нужно с процедурного подхода, критичные по скорости участки писать с использованием процедурного подхода а не ООП и т.д.
280 romix
 
модератор
07.02.07
15:13
(277) Ты часто используешь виртуальные деструкторы? Я так вообще не знаю что это такое (и как это может работать), мне это ск. всего никогда не потребуется.
Тем более что как ты говоришь там легко накосячить.
281 Трезвый взгляд
 
07.02.07
15:16
(275) В условиях нынешней бурной жизни этот переход может так и не состояться. И получатся в результате горе-объедкники, смело разбивающие орех абстракции и инкапсуляции своим намозоленным процедурным кулаком.

Если обезьяне не удаётся сбивать кокосы микроскопом, то микроскоп тут ни при чём.
282 Elkmor
 
07.02.07
15:21
(280) гы... :)) а что, бывают невиртуальные деструкторы? :)) Что произойдет с отпрыском в случае уничтожения потомка?
283 Трезвый взгляд
 
07.02.07
15:21
"ООП позволяет писать плохой, неэффективный и запутанный код, и провоцирует именно такой код."
"...процедурный подход намного меньше провоцирует на плохой код, и дает меньше возможностй для такого кода."

Вот те раз!... От NS такого не ожидал, признаться...

Писать плохой неэффективный и запутанный код позволяет и провоцирует не какая-то определённая методика, а недостаток знаний и навыков.
284 Elkmor
 
07.02.07
15:21
(282) В случае уничтожение родителя имел в виду :)
285 Elkmor
 
07.02.07
15:22
(283) +1
286 romix
 
модератор
07.02.07
15:27
(279) >ООП позволяет писать плохой, неэффективный и запутанный код, и провоцирует именно такой код.

Не знаю что там можно запутать или ухудшить по сравнению с процедурным стилем.
По-моему появляются только новые возможности, а процедура как была там, так и осталась, только она вложена "под шапку" класса.

А развесистые экспертные суждения неплохо бы и обосновывать (например, ссылкой).
287 romix
 
модератор
07.02.07
15:30
Я понял, NS тут всех разводит. :-)
Фигня например уже повелся.
288 NS
 
07.02.07
16:03
Не развожу. Доп. возможности как раз и провоцируют.
Ссылку на пример плохого (медленного) кода спровоцированного ООП я дал, причем этот код приводился как достоинство ООП.
289 NS
 
07.02.07
16:05
Кстати - мнение об опасности ООП на начальных стадиях освоения программирования не только моё. Так считают многие преподаватели. Ссылки на статьи можно поискать.
290 Elkmor
 
07.02.07
16:12
(289) Это просто чайники-непрофессионалы, которые НЕ ПОНЯЛИ ООП, и боятся его понимать, и оправдывают это тем что якобы вредно.
291 NS
 
07.02.07
16:15
(290) Хьятт - Автор Крейблиц, легендарной программы чемпионки мира по шахматам, трижды доктор наук, код которого многими признается образцовым, Crafty, текущая шахматная программа которого входит в тест SPEC CPU - чайник-непрофессинал? :)
292 NS
 
07.02.07
16:18
293 Elkmor
 
07.02.07
16:22
(291) да, а что делать? хороший алгоритмист/математик - не означает хороший прикладник, и не означает хороший программист в принципе.
294 NS
 
07.02.07
16:37
(293)Он ен математик :) Он программист. Он занимается компьютерной наукой.
Причем тут математик/алгоритмист??? Все программисты отчасти математики/алгоритмисты, а он именно один их сильнйших Американских программистов, причем преподаватель.

То есть пограммист он Плохой, а в Интел, в АМД - настолько идиоты что используют его код в качестве бразцового, тесового, в Университетах настолько тупое руководство что дает иму докторов и допускает к преподаванию. В Америке настолько тупое правительство, что фактически возвело его в ранг легенды компьютерной науки (программирования)?
295 spock
 
07.02.07
16:37
"знатоки" могут расценивать классы как namespase - упрощает понимание.
Читал, что наоборот, те кто сразу начинал программировать по ООП-парадигме с использованием паттернов пишут хороший код.
296 spock
 
07.02.07
17:34
(277)Без виртуального деструктора в этом коде будут утечки:
#include <iostream>

class Base
{
public:
   Base() {std::cout << "Base::Base()" << std::endl;};
   /*virtual*/ ~Base() {std::cout << "Base::~Base()" << std::endl;};
};

class Derived : public Base
{
public:
   Derived() {std::cout << "Derived::Derived()" << std::endl;};
   /*virtual*/ ~Derived() {std::cout << "Derived::~Derived()" << std::endl;};
};

int main(void)
{
   std::cout << "Hello, NS. That's memory leaks..." << std::endl;
   std::cout << "---------------------------------" << std::endl;

   Base* pObj = new Derived;

   /* do somethings */

   delete pObj;

   std::cout << "---------------------------------" << std::endl;

   return 0;
}

Если же virtual разремить, то будет ок.
297 Фигня
 
07.02.07
17:59
(287) Как уесть хочется, только не знаешь чем. Если внимательно читал, то я как раз указывал, что для обыденного приложения да еще под винду особой разницы не заметно.
.
Для критических приложений процедурное решение быстрее, особенно если учесть тонкости реализации компилятора. Тем не менее объектное решение МОЖНО довести до такой же производительности при ГРАМОТНОМ проектировании и программировании. И вот тут NS прав 100%: ООП провоцирует на неряшливый код. Отладить же объектный код значительно сложнее при большой вложенности. Опять же основные уязвимые места ООП программ утечки памяти от неграмотных деструкторов, а процедурных программ переполнение стека. Что лучше решать лично.
.
И еще немного из истории. В свое время Борланд публиковал баг-лист к апдейтам на С++ (не знаю как сейчас). Основные правки багов относились к работе конструкторов/деструкторов при вложении и наследовании. Т. е. убирались источники утечек памяти. Механизм, конечно, усовершенствовался, но тем не менее это показательный пример. Ну и опять же все, с кем сталкивался и реально писАли ООП, утверждали о необходимости жесткой дисциплины при кодировании. У нас же раздолбайство национальный бич.
298 romix
 
модератор
07.02.07
18:24
(296) Не юзаю я наследование.
А вообще его юзать хороший стиль, кто как думает?
299 romix
 
модератор
07.02.07
18:26
(297) >ООП провоцирует на неряшливый код. Отладить же объектный код значительно сложнее при большой вложенности.


Может быть тут речь идет не обо всем ООП, а только о наследовании?
Раз Борланд его долго отлаживала, значит сама не юзала в своих разработках (имхо).
300 NS
 
07.02.07
18:42
ООП это не только возможность указания методов через точку, ели бы это было так - то это была бы просто другая запись вызова процедуры/функций. :)
О проблемах которые вызывает ООП на больших проектах, и особенно при низкой квалификации разработчиков говорят тоже многие. Могу привести еще один пример, когда сам разработчик запутался в документации, и понять всю иерархию объектов никто не в состоянии - это MFC. Причем разрабатывалась библиотека не студентами :)
301 romix
 
модератор
07.02.07
18:54
(300) Обращение через точку, плюс возможность создавать множество однотипных объектов (таких как текстовые файлы). Без ООП это делать неудобно, и можно запутаться в множестве имен.
302 romix
 
модератор
07.02.07
18:55
(300) Ты считаешь что MFC надо было писать в процедурном стиле, тогда бы не запутались в документации? Или что (какой стиль) им можно было поюзать, чтобы не испытывать таких затруднений?
303 NS
 
07.02.07
19:17
Ромикс, я уже второй день говорю об одном и том-же. ООП нет места в двух случаях - в критичных по скорости участках кода, и в случае недостаточной квалификации разработчиков.

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

Ситуация с 1С - в более чем 50% случаев приезжая к клиенту видишь что пограмма не проходит элементарный Синтаксис-Контроль. Нельзя давать этим разработчикам в руки инструменты типа ООП. Конфигурации станут неподдерживаемыми. Совсем.

Ты меня переиначиваешь - я не говорю о том что ОО Подход не нужен и вреден всегда. Я говорю о том, что бывают ситуации, когда разработчика лучше ограничить в возможностях. Это так-же как нельзя давать детям в руки мотоцикл который способен развивать скорость 300км/час.
304 romix
 
модератор
07.02.07
19:30
(303) NS ты уже задолбал разводить.
Сегодня не 1 апреля.

"безопасных подходов - не использовать указатели, не использовать ООП"

...не использовать исключения, не использовать циклы...
305 romix
 
модератор
07.02.07
19:32
Если ты на полном серьезе тогда я не знаю откуда ты это вынес.
Не было этого по-моему нигде в литературе, если же это новое веяние такое, то надо хорошо посмотреть, не развод, не шутка ли это.
306 NS
 
07.02.07
19:33
(304) Не использовать оператор GOTO.
В чем развод? Ты видишь тут развод?
Ты возмешь студента только окончившего школу на работу, и позволишь ему спроектировать космический корабль, и пошлешь на нем живых людей на Марс?
Нужно хоть немного обращать внимание на реальную сложившуюся ситуацию.
307 Garykom
 
гуру
07.02.07
19:51
ООП - это написание и последующее применение "черных ящиков" - классов объектов.
ПП - это когда ящики (процедуры и функции) нельзя применять если они чуть-чуть не подходят - надо их переделывать.
В ООП ящики можно подстраивать переопределяя методы, т.е. не нужно копи-пастить куски кода (который причем может быть закрыт). Причем ящики ПП (процедуры и функции) никуда не делись и их по прежнему можно использовать.
308 Фигня
 
07.02.07
21:38
(299) Наследование одно из базовых свойств ООП. И Борланд АКТИВНО его юзал. В ДОС была библиотека TurboVision, под винду свой аналог MFC (не помню сейчас названия), сейчас VCL. Промах.
.
(298) А нафига тогда ООП?
.
Ромикс, ты кроме мануалов что-то читаешь? Хоть что-то базовое? Иначе такой хери не нес бы. Как пример не ты ли рвал жпо в свое время по поводу класса "документ" в самопале а-ля 1С в очередном флейме? И как ты собирался щтамповать документы без наследования?
.
Обратите еще внимание, что полностью объектные Java и C# не являются классическими компиляторами даже в случае JIT. Всегда присутствует garbage collector, рулящий памятью. Что как раз снижает остроту безграмотного проектирования деструкторов. Этажом выше был задан хороший вопрос: что будет с потомком при уничтожении родителя?
.
Основные киты ООП наследование/полиморфизм/инкапсуляция/перегрузка одновременно являются источником грабель для неосторожного прогера. В (303) хороший пример. Только в первом абзаце я поменял бы местами неприменимость ООП. В первую очередь ООП неприменимо при недостаточной квалификации разработчика и только потом для критических приложений. Потому что в ряде случаев все-таки удается сравнять скорости. Лично я наваял в порядке пробы драйвер реального времени спецжелезки под ДОС обоими способами. Процедурно было легче, но объектно тоже удалось. При почти одинаковой скорости объектный вариант ваять было в разЫ сложнее. Ну и упомяну проект HURD, микроядерная ось. Часть с ООП, часть процедурная. Разницы в аналогах не замечено.
309 romix
 
07.02.07
23:58
Инкапсуляция тоже является источником грабель?
310 v77
 
08.02.07
08:45
Абалдеть! Во людям делать нечего :)))
311 orefkov
 
08.02.07
09:06
Написание крутой шахматной программы имхо еще не показатель состоятельности програмиста. Теория есть, взаимодействие с пользователем минимально, таксать "вещь в себе". С это точки зрения написание какогонить допустим текстового процессора с развитым функционалом гораздо сложнее. А то что у NS'а не получается совместить скорость работы и ООП подход - скорее всего, слабое звено здесь не ООП.
312 Elkmor
 
08.02.07
09:16
(294) его мнение - это просто мнение. Это не Истина в последней инстанции. Лично я испытывал затруднения с проектированием классов в ООП только на самых ранних этапах - где-то в первый год. Так что ничего и не слышал о каких-то проблемах, которые якобы подталкивали меня к написанию слишком сложного кода. Даже если я где-то написал лишние set/get, то это с лихвой окупилось преимуществами ООП.

И вообще, лучше почитать что-то про ООП, если его не испоьлзуешь, чтобы не критиковать лишний раз, к примеру "С++ для чайников" - самая лучшая книга на эту тему.
313 romix
 
модератор
08.02.07
10:09
(+309) up
314 Magic74
 
08.02.07
10:31
(56) override string ToString()
315 NS
 
08.02.07
11:59
(311) Читай внимательно ветку.
СИЛЬНЕЙШИЕ РАЗРАБОТЧИКИ шахматных программ, говорят о трехкратном падении быстродействия от ОО подхода. Так что давай, на форум шахматных программистов, и там выставляй себя идиотом. ТЫ видел текст Крафти? Фрукта? Ты не зная о чем говоришь лепишь откровенную чушь, да еще и меня оскорбляешь.

У меня - получается. Более того я использую и точку, и объекты (объекты только в шахматной программе) - Мест где возможен ОО подход в шахматной программе - не больше одного процента. Поэтому многие пишут шахматы вообще не на С++, а на С.
316 NS
 
08.02.07
12:04
(312) Опять я про одно, ты про другое. У Хьятта нет проблем, проблемы у его студентов. Он, как преподаватель - видит что вытворяют студенты если сразу давать им ООП, и поэтому говорит о том, что УЧИТЬ НАДО НАЧИНАТЬ с процедурного подхода. Ты чуствуешь разницу? Ни я нигде в этой ветке, ни Хьятт не говорят о том что ООП это плохо. Говорят о том что ООП - это беда при низкой квалифиуации разработчиков. И что в критичных по скорости участках кода ООП неприменимо. Так как не должно быть ни лишних расчетов Адреса, и тем более не должно быть ни одного вызова с сохранением регистров (переменных) в стек.
317 NS
 
08.02.07
12:07
(311) Орефков, ты хоть раз писал что-нибудь критичное к скорости - ссылку!!!
Ты помоему вообще не въезжаешь, и не понимаешь что ткое модуль на 10000 строк без единой переменной в памяти, всё в регистрах, и где нет места лишним регистрам для вычисления адреса,  тем более недопустимы никакие вызовы.

Для самообразования возми и посмотри процедуры Eval в Крфти (Битбоард представление доски) и в Фрукте (Байтовое представление доски) - хоть будешь знать о чем идет речь. И еще раз - говоря о скорости, и о критичных к скорости приложениях - ты вообще о чем говоришь? ДАЙ ССЫЛКУ.
318 Elkmor
 
08.02.07
12:08
(316) Я за то же :) немного запутался в диалогах ;) ООП от первоклашек держать подальше!
319 NS
 
08.02.07
12:10
(318) От Первоклашек, и от 1Сников. :)
Я уже восемь лет работаю с 1С, и знаю квалификацию "среднего" разработчика.
320 NS
 
08.02.07
12:11
Извиняюсь - почти девять лет.
321 Ненавижу 1С
 
гуру
08.02.07
12:14
(319) негодяй! нет чтоб доброе, светлое в 1С! а он подальше держать?
322 NS
 
08.02.07
12:16
(321) Дали в 1С Goto, понятно, что бывают случаи когда дествительно удобно.
Ваня Пушкин не даст соврать - взяли девочку на работу, попросили написать простейший отчет по регистру. Запрос на три строчки, и в цикле вывод в таблицу.

Она умудрилась написать абсолютно неработающий кусок на 100 строк, с двадцатью метками, и постоянными перекрестными переходами. А ты говоришь ООП ей. :)
323 Ненавижу 1С
 
гуру
08.02.07
12:28
(322) Инструмент должен быть, проста некоторые могут(должны) его не использовать. Кто-то будет писать классы, кто-то только их использовать. Яркий пример Делфи: подходит всем и кто пишет свои классы и кто пользует его как ВижуалБасик.
324 NS
 
08.02.07
12:32
(323) Что будет если дать возможность детскому мокику развивать скорость 200км/час? Инструмент же должен быть, дети просто небудут им пользоваться. Правильно?
325 NS
 
08.02.07
13:10
Вот специально для "гениев, мастеров оптимизации быстродействия" типа Орефкова.
Образец исполнителя хода из Крафти, всё в регистрах.
Считается образцовым кодом, ни одного Call, ни одной переменной в памяти.
Перепиши на объектах.

piece = Piece(move);
 from = From(move);
 to = To(move);
 captured = Captured(move);
 promote = Promote(move);
MakePieceMove:
 bit_move = SetMask(from) | SetMask(to);
 bit_move_rl45 = SetMaskRL45(from) | SetMaskRL45(to);
 bit_move_rr45 = SetMaskRR45(from) | SetMaskRR45(to);
 bit_move_rl90 = SetMaskRL90(from) | SetMaskRL90(to);
 ClearSet(bit_move_rl45, OccupiedRL45);
 ClearSet(bit_move_rr45, OccupiedRR45);
 ClearSet(bit_move_rl90, OccupiedRL90);
 PcOnSq(from) = 0;
 switch (piece) {
/*
*******************************************************************************
*                                                                             *
*   make pawn moves.  there are two special cases:  (a) enpassant captures    *
*   where the captured pawn is not on the "to" square and must be removed in  *
*   a different way, and (2) pawn promotions (where the "Promote" variable    *
*   is non-zero) requires updating the appropriate bit boards since we are    *
*   creating a new piece.                                                     *
*                                                                             *
*******************************************************************************
*/
 case pawn:
   if (wtm) {
     ClearSet(bit_move, WhitePawns);
     ClearSet(bit_move, WhitePieces);
     HashPW(from, HashKey);
     HashPW(from, PawnHashKey);
     HashPW(to, HashKey);
     HashPW(to, PawnHashKey);
     if (captured == 1) {
       if (!PcOnSq(to)) {
         ClearRL90(to - 8, OccupiedRL90);
         ClearRL45(to - 8, OccupiedRL45);
         ClearRR45(to - 8, OccupiedRR45);
         Clear(to - 8, BlackPawns);
         Clear(to - 8, BlackPieces);
         HashPB(to - 8, HashKey);
         HashPB(to - 8, PawnHashKey);
         PcOnSq(to - 8) = 0;
         Material += pawn_value;
         TotalBlackPawns--;
         TotalPieces--;
         captured = 0;
       }
     }
     PcOnSq(to) = pawn;
/*
**********************************************************************
*                                                                    *
*  if this is a pawn promotion, remove the pawn from the counts      *
*  then update the correct piece board to reflect the piece just     *
*  created.                                                          *
*                                                                    *
**********************************************************************
*/
     if (promote) {
       TotalWhitePawns--;
       Material -= pawn_value;
       Clear(to, WhitePawns);
       HashPW(to, HashKey);
       HashPW(to, PawnHashKey);
       switch (promote) {
       case knight:
         Set(to, WhiteKnights);
         HashNW(to, HashKey);
         PcOnSq(to) = knight;
         TotalWhitePieces += knight_v;
         WhiteMinors++;
         Material += knight_value;
         break;
       case bishop:
         Set(to, WhiteBishops);
         Set(to, BishopsQueens);
         HashBW(to, HashKey);
         PcOnSq(to) = bishop;
         TotalWhitePieces += bishop_v;
         WhiteMinors++;
         Material += bishop_value;
         break;
       case rook:
         Set(to, WhiteRooks);
         Set(to, RooksQueens);
         HashRW(to, HashKey);
         PcOnSq(to) = rook;
         TotalWhitePieces += rook_v;
         WhiteMajors++;
         Material += rook_value;
         break;
       case queen:
         Set(to, WhiteQueens);
         Set(to, BishopsQueens);
         Set(to, RooksQueens);
         HashQW(to, HashKey);
         PcOnSq(to) = queen;
         TotalWhitePieces += queen_v;
         WhiteMajors += 2;
         Material += queen_value;
         break;
       }
     } else if (((to - from) == 16) && (mask_eptest[to] & BlackPawns)) {
       EnPassant(ply + 1) = to - 8;
       HashEP(to - 8, HashKey);
     }
   } else {
     ClearSet(bit_move, BlackPawns);
     ClearSet(bit_move, BlackPieces);
     HashPB(from, HashKey);
     HashPB(from, PawnHashKey);
     HashPB(to, HashKey);
     HashPB(to, PawnHashKey);
     if (captured == 1) {
       if (!PcOnSq(to)) {
         ClearRL90(to + 8, OccupiedRL90);
         ClearRL45(to + 8, OccupiedRL45);
         ClearRR45(to + 8, OccupiedRR45);
         Clear(to + 8, WhitePawns);
         Clear(to + 8, WhitePieces);
         HashPW(to + 8, HashKey);
         HashPW(to + 8, PawnHashKey);
         PcOnSq(to + 8) = 0;
         Material -= pawn_value;
         TotalWhitePawns--;
         TotalPieces--;
         captured = 0;
       }
     }
     PcOnSq(to) = -pawn;
/*
326 Ненавижу 1С
 
гуру
08.02.07
13:20
А вот, что я надыбал в Делфи:
ShowMessage(MetaClass['MyClass']['NAME']);
327 v77
 
08.02.07
13:25
NS неистовый какой то. ООП детям не игрушка!!! Прям пальцы дети себе пообрывают пока сообразят, что такое указатели, конструкторы и деструкторы.
328 NS
 
08.02.07
13:25
Чтоб Орефкову было понятней - весь код исполнителя хода.
Еще раз повторю -это считается один из быстрейших кодов, и этот код считается образцовым и используется для тестирования процов и компиляторов (входит в SPEC CPU)

Ежели Орефков не в состоянии дать ссылки на свои проекты именно критичные к быстродйствию, и не в состоянии переписать этот код на объектов, хотя-бы всего с двухкратным падением быстродейтсвия. То следу6ет признать что господин Орефков просто трепло и ХАМ.

#include <stdio.h>
#include <stdlib.h>
#include "chess.h"
#include "data.h"

/* last modified 08/23/99 */
/*
*******************************************************************************
*                                                                             *
*   MakeMove() is responsible for updating the position database whenever a   *
*   piece is moved.  it performs the following operations:  (1) update the    *
*   board structure itself by moving the piece and removing any captured      *
*   piece.  (2) update the hash keys.  (3) update material counts.  (4) update*
*   castling status.  (5) update number of moves since last reversible move.  *
*                                                                             *
*******************************************************************************
*/
void MakeMove(TREE * RESTRICT tree, int ply, int move, int wtm)
{
 register int piece, from, to, captured, promote;
 BITBOARD bit_move, bit_move_rl45, bit_move_rr45, bit_move_rl90;

/*
************************************************************
*                                                          *
*   first, clear the EnPassant_Target bit-mask.  moving a  *
*   pawn two ranks will set it later in MakeMove().        *
*                                                          *
************************************************************
*/
#if defined(DEBUG)
 ValidatePosition(tree, ply, move, "MakeMove(1)");
#endif
 tree->position[ply + 1] = tree->position[ply];
 tree->save_hash_key[ply] = HashKey;
 tree->save_pawn_hash_key[ply] = PawnHashKey;
 if (EnPassant(ply + 1)) {
   HashEP(EnPassant(ply + 1), HashKey);
   EnPassant(ply + 1) = 0;
 }
 Rule50Moves(ply + 1)++;
/*
************************************************************
*                                                          *
*   now do the piece-specific things by calling the        *
*   appropriate routine.                                   *
*                                                          *
************************************************************
*/
 piece = Piece(move);
 from = From(move);
 to = To(move);
 captured = Captured(move);
 promote = Promote(move);
MakePieceMove:
 bit_move = SetMask(from) | SetMask(to);
 bit_move_rl45 = SetMaskRL45(from) | SetMaskRL45(to);
 bit_move_rr45 = SetMaskRR45(from) | SetMaskRR45(to);
 bit_move_rl90 = SetMaskRL90(from) | SetMaskRL90(to);
 ClearSet(bit_move_rl45, OccupiedRL45);
 ClearSet(bit_move_rr45, OccupiedRR45);
 ClearSet(bit_move_rl90, OccupiedRL90);
 PcOnSq(from) = 0;
 switch (piece) {
/*
*******************************************************************************
*                                                                             *
*   make pawn moves.  there are two special cases:  (a) enpassant captures    *
*   where the captured pawn is not on the "to" square and must be removed in  *
*   a different way, and (2) pawn promotions (where the "Promote" variable    *
*   is non-zero) requires updating the appropriate bit boards since we are    *
*   creating a new piece.                                                     *
*                                                                             *
*******************************************************************************
*/
 case pawn:
   if (wtm) {
     ClearSet(bit_move, WhitePawns);
     ClearSet(bit_move, WhitePieces);
     HashPW(from, HashKey);
     HashPW(from, PawnHashKey);
     HashPW(to, HashKey);
     HashPW(to, PawnHashKey);
     if (captured == 1) {
       if (!PcOnSq(to)) {
         ClearRL90(to - 8, OccupiedRL90);
         ClearRL45(to - 8, OccupiedRL45);
         ClearRR45(to - 8, OccupiedRR45);
         Clear(to - 8, BlackPawns);
         Clear(to - 8, BlackPieces);
         HashPB(to - 8, HashKey);
         HashPB(to - 8, PawnHashKey);
         PcOnSq(to - 8) = 0;
         Material += pawn_value;
         TotalBlackPawns--;
         TotalPieces--;
         captured = 0;
       }
     }
     PcOnSq(to) = pawn;
/*
**********************************************************************
*                                                                    *
*  if this is a pawn promotion, remove the pawn from the counts      *
*  then update the correct piece board to reflect the piece just     *
*  created.                                                          *
*                                                                    *
**********************************************************************
*/
     if (promote) {
       TotalWhitePawns--;
       Material -= pawn_value;
       Clear(to, WhitePawns);
       HashPW(to, HashKey);
       HashPW(to, PawnHashKey);
       switch (promote) {
       case knight:
         Set(to, WhiteKnights);
         HashNW(to, HashKey);
         PcOnSq(to) = knight;
         TotalWhitePieces += knight_v;
         WhiteMinors++;
         Material += knight_value;
         break;
       case bishop:
         Set(to, WhiteBishops);
         Set(to, BishopsQueens);
         HashBW(to, HashKey);
         PcOnSq(to) = bishop;
         TotalWhitePieces += bishop_v;
         WhiteMinors++;
         Material += bishop_value;
         break;
       case rook:
         Set(to, WhiteRooks);
         Set(to, RooksQueens);
         HashRW(to, HashKey);
         PcOnSq(to) = rook;
         TotalWhitePieces += rook_v;
         WhiteMajors++;
         Material += rook_value;
         break;
       case queen:
         Set(to, WhiteQueens);
         Set(to, BishopsQueens);
         Set(to, RooksQueens);
         HashQW(to, HashKey);
         PcOnSq(to) = queen;
         TotalWhitePieces += queen_v;
         WhiteMajors += 2;
         Material += queen_value;
         break;
       }
     } else if (((to - from) == 16) && (mask_eptest[to] & BlackPawns)) {
       EnPassant(ply + 1) = to - 8;
       HashEP(to - 8, HashKey);
     }
   } else {
     ClearSet(bit_move, BlackPawns);
     ClearSet(bit_move, BlackPieces);
     HashPB(from, HashKey);
     HashPB(from, PawnHashKey);
     HashPB(to, HashKey);
     HashPB(to, PawnHashKey);
     if (captured == 1) {
       if (!PcOnSq(to)) {
         ClearRL90(to + 8, OccupiedRL90);
         ClearRL45(to + 8, OccupiedRL45);
         ClearRR45(to + 8, OccupiedRR45);
         Clear(to + 8, WhitePawns);
         Clear(to + 8, WhitePieces);
         HashPW(to + 8, HashKey);
         HashPW(to + 8, PawnHashKey);
         PcOnSq(to + 8) = 0;
         Material -= pawn_value;
         TotalWhitePawns--;
         TotalPieces--;
         captured = 0;
       }
     }
     PcOnSq(to) = -pawn;
/*
**********************************************************************
*                                                                    *
*  if this is a pawn promotion, remove the pawn from the counts      *
*  then update the correct piece board to reflect the piece just     *
*  created.                                                          *
*                                                                    *
**********************************************************************
*/
     if (promote) {
       TotalBlackPawns--;
       Material += pawn_value;
       Clear(to, BlackPawns);
       HashPB(to, HashKey);
       HashPB(to, PawnHashKey);
       switch (promote) {
       case knight:
         Set(to, BlackKnights);
         HashNB(to, HashKey);
         PcOnSq(to) = -knight;
         TotalBlackPieces += knight_v;
         BlackMinors++;
         Material -= knight_value;
         break;
       case bishop:
         Set(to, BlackBishops);
         Set(to, BishopsQueens);
         HashBB(to, HashKey);
         PcOnSq(to) = -bishop;
         TotalBlackPieces += bishop_v;
         BlackMinors++;
         Material -= bishop_value;
         break;
       case rook:
         Set(to, BlackRooks);
         Set(to, RooksQueens);
         HashRB(to, HashKey);
         PcOnSq(to) = -rook;
         TotalBlackPieces += rook_v;
         BlackMajors++;
         Material -= rook_value;
         break;
       case queen:
         Set(to, BlackQueens);
         Set(to, BishopsQueens);
         Set(to, RooksQueens);
         HashQB(to, HashKey);
         PcOnSq(to) = -queen;
         TotalBlackPieces += queen_v;
         BlackMajors += 2;
         Material -= queen_value;
         break;
       }
     } else if (((from - to) == 16) && (mask_eptest[to] & WhitePawns)) {
       EnPassant(ply + 1) = to + 8;
       HashEP(to + 8, HashKey);
     }
   }
   Rule50Moves(ply + 1) = 0;
   break;
/*
*******************************************************************************
*                                                                             *
*   make knight moves.                                                        *
*                                                                             *
*******************************************************************************
*/
 case knight:
   if (wtm) {
     ClearSet(bit_move, WhiteKnights);
     ClearSet(bit_move, WhitePieces);
     HashNW(from, HashKey);
     HashNW(to, HashKey);
     PcOnSq(to) = knight;
   } else {
     ClearSet(bit_move, BlackKnights);
     ClearSet(bit_move, BlackPieces);
     HashNB(from, HashKey);
     HashNB(to, HashKey);
     PcOnSq(to) = -knight;
   }
   break;
/*
*******************************************************************************
*                                                                             *
*   make bishop moves.                                                        *
*                                                                             *
*******************************************************************************
*/
 case bishop:
   Clear(from, BishopsQueens);
   Set(to, BishopsQueens);
   if (wtm) {
     ClearSet(bit_move, WhiteBishops);
     ClearSet(bit_move, WhitePieces);
     HashBW(from, HashKey);
     HashBW(to, HashKey);
     PcOnSq(to) = bishop;
   } else {
     ClearSet(bit_move, BlackBishops);
     ClearSet(bit_move, BlackPieces);
     HashBB(from, HashKey);
     HashBB(to, HashKey);
     PcOnSq(to) = -bishop;
   }
   break;
/*
*******************************************************************************
*                                                                             *
*   make rook moves.  the only special case handling required is to determine *
*   if x_castle is non-zero [x=w or b based on side to move].  if it is non-  *
*   zero, the value must be corrected if either rook is moving from its       *
*   original square, so that castling with that rook becomes impossible.      *
*                                                                             *
*******************************************************************************
*/
 case rook:
   Clear(from, RooksQueens);
   Set(to, RooksQueens);
   if (wtm) {
     ClearSet(bit_move, WhiteRooks);
     ClearSet(bit_move, WhitePieces);
     HashRW(from, HashKey);
     HashRW(to, HashKey);
     PcOnSq(to) = rook;
     if (WhiteCastle(ply + 1) > 0) {
       if ((from == A1) && (WhiteCastle(ply + 1) & 2)) {
         WhiteCastle(ply + 1) &= 1;
         HashCastleW(1, HashKey);
       } else if ((from == H1) && (WhiteCastle(ply + 1) & 1)) {
         WhiteCastle(ply + 1) &= 2;
         HashCastleW(0, HashKey);
       }
     }
   } else {
     ClearSet(bit_move, BlackRooks);
     ClearSet(bit_move, BlackPieces);
     HashRB(from, HashKey);
     HashRB(to, HashKey);
     PcOnSq(to) = -rook;
     if (BlackCastle(ply + 1) > 0) {
       if ((from == A8) && (BlackCastle(ply + 1) & 2)) {
         BlackCastle(ply + 1) &= 1;
         HashCastleB(1, HashKey);
       } else if ((from == H8) && (BlackCastle(ply + 1) & 1)) {
         BlackCastle(ply + 1) &= 2;
         HashCastleB(0, HashKey);
       }
     }
   }
   break;
/*
*******************************************************************************
*                                                                             *
*   make queen moves                                                          *
*                                                                             *
*******************************************************************************
*/
 case queen:
   Clear(from, BishopsQueens);
   Set(to, BishopsQueens);
   Clear(from, RooksQueens);
   Set(to, RooksQueens);
   if (wtm) {
     ClearSet(bit_move, WhiteQueens);
     ClearSet(bit_move, WhitePieces);
     HashQW(from, HashKey);
     HashQW(to, HashKey);
     PcOnSq(to) = queen;
   } else {
     ClearSet(bit_move, BlackQueens);
     ClearSet(bit_move, BlackPieces);
     HashQB(from, HashKey);
     HashQB(to, HashKey);
     PcOnSq(to) = -queen;
   }
   break;
/*
*******************************************************************************
*                                                                             *
*   make king moves.  the only special case is castling, which is indicated   *
*   by from=E1, to=G1 for o-o as an example.  the king is moving from e1-g1   *
*   which is normally illegal.  in this case, the correct rook is also moved. *
*                                                                             *
*   note that moving the king in any direction resets the x_castle [x=w or b] *
*   flag indicating that castling is not possible in *this* position.         *
*                                                                             *
*******************************************************************************
*/
 case king:
   if (wtm) {
     ClearSet(bit_move, WhitePieces);
     HashKW(from, HashKey);
     HashKW(to, HashKey);
     PcOnSq(to) = king;
     WhiteKingSQ = to;
     if (WhiteCastle(ply + 1) > 0) {
       if (WhiteCastle(ply + 1) & 2)
         HashCastleW(1, HashKey);
       if (WhiteCastle(ply + 1) & 1)
         HashCastleW(0, HashKey);
       if (abs(to - from) == 2)
         WhiteCastle(ply + 1) = -ply;
       else
         WhiteCastle(ply + 1) = 0;
       if (abs(to - from) == 2) {
         piece = rook;
         if (to == G1) {
           from = H1;
           to = F1;
           goto MakePieceMove;
         } else {
           from = A1;
           to = D1;
           goto MakePieceMove;
         }
       }
     }
   } else {
     ClearSet(bit_move, BlackPieces);
     HashKB(from, HashKey);
     HashKB(to, HashKey);
     PcOnSq(to) = -king;
     BlackKingSQ = to;
     if (BlackCastle(ply + 1) > 0) {
       if (BlackCastle(ply + 1) & 2)
         HashCastleB(1, HashKey);
       if (BlackCastle(ply + 1) & 1)
         HashCastleB(0, HashKey);
       if (abs(to - from) == 2)
         BlackCastle(ply + 1) = -ply;
       else
         BlackCastle(ply + 1) = 0;
       if (abs(to - from) == 2) {
         piece = rook;
         if (to == G8) {
           from = H8;
           to = F8;
           goto MakePieceMove;
         } else {
           from = A8;
           to = D8;
           goto MakePieceMove;
         }
       }
     }
   }
   break;
 }
/*
*******************************************************************************
*                                                                             *
*   now it is time to "gracefully" remove a piece from the game board since it*
*   is being captured.  this includes updating the board structure.           *
*                                                                             *
*******************************************************************************
*/
 if (captured) {
   Rule50Moves(ply + 1) = 0;
   TotalPieces--;
   if (promote)
     piece = promote;
   SetRL45(to, OccupiedRL45);
   SetRR45(to, OccupiedRR45);
   SetRL90(to, OccupiedRL90);
   switch (captured) {
/*
************************************************************
*                                                          *
*   remove a captured pawn.                                *
*                                                          *
************************************************************
*/
   case pawn:
     if (wtm) {
       Clear(to, BlackPawns);
       Clear(to, BlackPieces);
       HashPB(to, HashKey);
       HashPB(to, PawnHashKey);
       Material += pawn_value;
       TotalBlackPawns--;
     } else {
       Clear(to, WhitePawns);
       Clear(to, WhitePieces);
       HashPW(to, HashKey);
       HashPW(to, PawnHashKey);
       Material -= pawn_value;
       TotalWhitePawns--;
     }
     break;
/*
************************************************************
*                                                          *
*   remove a captured knight.                              *
*                                                          *
************************************************************
*/
   case knight:
     if (wtm) {
       Clear(to, BlackKnights);
       Clear(to, BlackPieces);
       HashNB(to, HashKey);
       TotalBlackPieces -= knight_v;
       BlackMinors--;
       Material += knight_value;
     } else {
       Clear(to, WhiteKnights);
       Clear(to, WhitePieces);
       HashNW(to, HashKey);
       TotalWhitePieces -= knight_v;
       WhiteMinors--;
       Material -= knight_value;
     }
     break;
/*
************************************************************
*                                                          *
*   remove a captured bishop.                              *
*                                                          *
************************************************************
*/
   case bishop:
     if (!SlidingDiag(piece))
       Clear(to, BishopsQueens);
     if (wtm) {
       Clear(to, BlackBishops);
       Clear(to, BlackPieces);
       HashBB(to, HashKey);
       TotalBlackPieces -= bishop_v;
       BlackMinors--;
       Material += bishop_value;
     } else {
       Clear(to, WhiteBishops);
       Clear(to, WhitePieces);
       HashBW(to, HashKey);
       TotalWhitePieces -= bishop_v;
       WhiteMinors--;
       Material -= bishop_value;
     }
     break;
/*
************************************************************
*                                                          *
*   remove a captured rook.                                *
*                                                          *
************************************************************
*/
   case rook:
     if (!SlidingRow(piece))
       Clear(to, RooksQueens);
     if (wtm) {
       Clear(to, BlackRooks);
       Clear(to, BlackPieces);
       HashRB(to, HashKey);
       if (BlackCastle(ply + 1) > 0) {
         if ((to == A8) && (BlackCastle(ply + 1) & 2)) {
           BlackCastle(ply + 1) &= 1;
           HashCastleB(1, HashKey);
         } else if ((to == H8) && (BlackCastle(ply + 1) & 1)) {
           BlackCastle(ply + 1) &= 2;
           HashCastleB(0, HashKey);
         }
       }
       TotalBlackPieces -= rook_v;
       BlackMajors--;
       Material += rook_value;
     } else {
       Clear(to, WhiteRooks);
       Clear(to, WhitePieces);
       HashRW(to, HashKey);
       if (WhiteCastle(ply + 1) > 0) {
         if ((to == A1) && (WhiteCastle(ply + 1) & 2)) {
           WhiteCastle(ply + 1) &= 1;
           HashCastleW(1, HashKey);
         } else if ((to == H1) && (WhiteCastle(ply + 1) & 1)) {
           WhiteCastle(ply + 1) &= 2;
           HashCastleW(0, HashKey);
         }
       }
       TotalWhitePieces -= rook_v;
       WhiteMajors--;
       Material -= rook_value;
     }
     break;
/*
************************************************************
*                                                          *
*   remove a captured queen.                               *
*                                                          *
************************************************************
*/
   case queen:
     if (!SlidingDiag(piece))
       Clear(to, BishopsQueens);
     if (!SlidingRow(piece))
       Clear(to, RooksQueens);
     if (wtm) {
       Clear(to, BlackQueens);
       Clear(to, BlackPieces);
       HashQB(to, HashKey);
       TotalBlackPieces -= queen_v;
       BlackMajors -= 2;
       Material += queen_value;
     } else {
       Clear(to, WhiteQueens);
       Clear(to, WhitePieces);
       HashQW(to, HashKey);
       TotalWhitePieces -= queen_v;
       WhiteMajors -= 2;
       Material -= queen_value;
     }
     break;
/*
************************************************************
*                                                          *
*   remove a captured king. [this is an error condition]   *
*                                                          *
************************************************************
*/
   case king:
     Print(128, "captured a king\n");
     Print(128, "piece=%d,from=%d,to=%d,captured=%d\n", piece, from, to,
         captured);
     Print(128, "ply=%d\n", ply);
     if (log_file)
       DisplayChessBoard(log_file, tree->pos);
   }
 }
#if defined(DEBUG)
 ValidatePosition(tree, ply + 1, move, "MakeMove(2)");
#endif
 return;
}

/*
*******************************************************************************
*                                                                             *
*   MakeMoveRoot() is used to make a move at the root of the game tree,       *
*   before any searching is done.  it uses MakeMove() to execute the move,    *
*   but then copies the resulting position back to position[0], the actual    *
*   board position.  it handles the special-case of the draw-by-repetition    *
*   rule by maintaining a list of previous positions, which is reset each time*
*   a non-reversible (pawn move or capture move) is made.                     *
*                                                                             *
*******************************************************************************
*/
void MakeMoveRoot(TREE * RESTRICT tree, int move, int wtm)
{
/*
************************************************************
*                                                          *
*   first, make the move and replace position[0] with the  *
*   new position.                                          *
*                                                          *
************************************************************
*/
 MakeMove(tree, 0, move, wtm);
/*
************************************************************
*                                                          *
*   now, if this is a non-reversible move, reset the       *
*   repetition list pointer to start the count over.       *
*                                                          *
************************************************************
*/
 if (Rule50Moves(1) == 0) {
   tree->rep_game = -1;
 }
 WhiteCastle(1) = Max(0, WhiteCastle(1));
 BlackCastle(1) = Max(0, BlackCastle(1));
 tree->position[0] = tree->position[1];
 tree->rep_list[++tree->rep_game] = HashKey;
}
329 NS
 
08.02.07
13:29
(327)
Конечно не игрушка. Вот Орефков, кстати явно специалист по ООП, деже не понимает какое падение скорости может дать использование ООП, и реально считает что можно написать код шахматной программы с использованием ООП без падения быстродействия. Но наверно он настотлько в нем погряз, что забыл уже что такое регистры процессора, что такое вызовы, что математичка и вычисления занимают время, а что сохранение регистров в стек вместе с вызовом и последующий инициализацией значений - просто убивает быстродйствие критичного к скорости кода.
330 v77
 
08.02.07
13:41
(329)"что такое регистры процессора, что такое вызовы, что математичка и вычисления занимают время," - да об этом любой программист знает. И орефков тоже знает. Ты чо так кипятишься? Ну вызовы виртуальных методов в ООП медленные. Зато  море других преимуществ. Ругать ООП незачто абсолютно. Можно весь код, который ты показал, засунуть в метод класса и ничего страшного.
331 NS
 
08.02.07
13:45
(330) Рассказать что я вкипятился? Орефков периодически рассуждает о том, в чем вообще не сечет.
Я привел примеры кода, то есть подтвержаю свои высказывания, могу дать ссылки на форумы посвященный шахматному программированию, где  сидят разработчики сильнейших программ - они подтвердят тоже самое - в шахматной программе в 99% кода нет места ООП. и ООП замедляет шахматную программу в три раза, так как во всех критичных к скорости процедурах, а это и есть вся шахматная программа (Оценка, генераторы, исполнители хода, проверка на шах и т.д.) Недопустимы переменные в памяти, лишние вычисления и недопустимы вызовы.


А что-же пишет Орефков, который при этом совсем не в теме?

   orefkov
  Написание крутой шахматной программы имхо еще не показатель состоятельности програмиста. Теория есть, взаимодействие с пользователем минимально, таксать "вещь в себе". С это точки зрения написание какогонить допустим текстового процессора с развитым функционалом гораздо сложнее. А то что у NS'а не получается совместить скорость работы и ООП подход - скорее всего, слабое звено здесь не ООП.
332 NS
 
08.02.07
13:47
И если Орефков не в курсе - то как раз написание сильной шахматной программы и есть показатель состоятельности программиста. Моя программа на данный момент третья по силе в России. Играет значительно сильнее и Легендарной Каиссы и т.д.
И это есть признак состоятельности.

А Орефков своими выказываниями только показывает что он гений-недоучка.
333 арефкофф
 
08.02.07
13:51
фсё-фсё, ты пабидил
334 NS
 
08.02.07
13:54
Да не победил. Орефков - придурок.
Если он меня оскорбляет, то и я этого писаку мелких плагинов и текстовых процессоров могу оскорблять.  Да у него силенок то программистких хватает только на написание автоматических переносов, да и на беганье курсора по тексту.
335 v77
 
08.02.07
14:07
Сделал выводы:
1. ООП медленнее, но писать как тот чувак с идеальным кодом я никогда не буду. Я не мазохист. Драйверов и шахматных программ не разрабатываю и уж как нибудь с классами и компонентами...
2. Шахматистов лучше не трогать, а то придурком будут обзываться.
336 NS
 
08.02.07
14:12
А при чем тут трогать? Орефков рассуждает о том, что вообще не понимает.

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

"Теория есть"

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

Поиски крепостей, поиски признаков (в том числе и мат. методами), расчет весов признаков и т.д.

Я просто не могу нормально относится к лохам, которые постоянно судят о том чего не знают.
и соответсвенный вывод можно сделать о квалификации Орефкова. Кроме как на написание простейших плагинов - он ни на что не способен, тем более неспособен написать что-либо полностью своё.
337 romix
 
модератор
08.02.07
14:16
338 NS
 
08.02.07
14:20
Кстати, Ромикс, а зачем потребовалось удалять посты в моем разделе???
339 romix
 
модератор
08.02.07
14:20
(336) Напоминаю участникам правило №2
Флейм в разделах 1С и IT не допускается.
Большие куски кода с объяснениями просьба помещать в КЗ в виде статьи.
340 ареффкафф
 
08.02.07
14:20
NS - ты неудачнег :) аткуси сибе пальтсы :)))
341 romix
 
модератор
08.02.07
14:21
(338) Хочешь восстанови но по-моему это зло.
342 NS
 
08.02.07
14:21
(339) В ответ на посягательство на мою квалификацию - разъяснение что же такое шахматное программирование - не является флеймом. И Орефков явно меня оскорбил.
343 v77
 
08.02.07
14:24
2(NS) Ghzv интересно стало про шахматы. А зачем нужны программы, которые в шахматы играют? От них польза есть какая нибудь? Или понты только?
Я чайник в этом. Так спросил. Интересно.
344 Mort
 
08.02.07
14:26
А я не понял в чем проблемма шахматной программе быть ООП.
345 v77
 
08.02.07
14:29
Да там выше написано. Типа медленно будет. Каспаров психует, когда соперник долго думает
346 NS
 
08.02.07
14:30
(343) Это считается одним из подразделов задачи создания Искуственного интелекта. Ввиду того что в шахматном программировании крутятся весьма серьезные деньги (Это нужно пользователям, за пол-года скачиваний моей программы приблизилось к миллиону) Все основные изобретения в распараллеливании переборных алгоритмов, в симих переборных алгоритмах, многие задачи распознования образов - впервые решаются именно шахматными программистами.

(344) Проблема в текстах которые я выложил - не место там ООП. Не получится применять объекты и методы, и тем более использовать иерархию объектов без сеьезного  падения производительности.

(345) В три раза медленней это -100 пунктов рейтинга к силе. Программа которая является сильнейшей в мире - станет простым середнячком. Одной из сотен.
И ользователю слабая программа не нужна.
347 romix
 
модератор
08.02.07
14:32
(342) Нормальный у него пост (хотя там есть чему возразить).

Я вот статью написал в КЗ (337).

Замедление может быть (т.к. заюзан один из регистров под ссылку на объект).
Но это не значит что все плохо: регистров у процессора больше, чем один, да и современные процессоры умеют использовать ОЗУ тоже достаточно эффективно (кешируют доступ к ОЗУ, надо лишь следить за линейками кеша, см. книгу Касперски по ссылке).

Если в твоем случае ссылка на объект не нужна ни в каком виде, то никто не заставляет юзать объекты, пиши процедурой. Но для значительной группы алгоритмов она есть, и если ты не будешь использовать объект (скажешь что это медленно и плохо), то обязательно поюзаешь переменную (например handle при доступе к файлу или окну в системе Windows). Машинный код при этом не факт что будет лучше (а ск. всего он будет хуже).
348 Mort
 
08.02.07
14:34
(346) Всё зависит от выбора абстракций. Например весь код в 328 просто может выполнять некая абстракция (класс) "игрок" и тогда прога будет ООП без потерь в скорости.
И ещё в 328, интересно а не будет ООП case-паттерн эффективней (т.е. быстрее) чем блок кейзов.
349 NS
 
08.02.07
14:35
(+343) Большинство авторов шахматных программ у них - либо изночально являются Докторами, известными учеными, либо защищаются на базе шахманой программы, на своих научных разработках.
Шахматное программирование кроме того что востребованно пользователями - еще и движет науку.

(347) Ромикс, Орефков сказал что я просто не умею использовать объекты. На что я говорю - что он даже примерно не в курсе что такое шахматная программа.
(348) Этот код, исполнитель хода, вызывается в Одном месте Программы!!!!

доска хранится в программе только один раз - один объект на всю программу.
Тоже самое со всеми остальными процедурами.
350 NS
 
08.02.07
14:37
348 - выше было написано - ООП может использоваться только в 1% кода шахматно программы, причем абсолютно непонятно зачем? Его использование возможно только в одном месте некритичном к скорости исполнения, в процедуре Search - в самих переборных алгоритмах, причем вызывается в нем каждаякритичная процедура только в одном месте, один раз.
351 NS
 
08.02.07
14:39
О блин - сколько у меня ошибок грамматических :)
352 NS
 
08.02.07
14:42
(348) Каким образом будет быстрее? Хороший компилятор переделывает Case в переход по вычисляемому адресу, без сравнений. Еще раз - этот код позволяет компилятору не использовать память, вызовы, минимизирует условия и т.д. Он считается образцовым. Объект Доска - сделать невозможно. Так как идет работа напрямую с битовым представлением позиции. А весь код шахматной программы завязан именно на доску.
353 romix
 
модератор
08.02.07
14:49
(349) Орефков этого не говорил. Он говорил про некое "узкое место", а это действительно может быть не объект как таковой (если он нужен алгоритмически, то зачем от него отказываться, в угоду чего? Чтобы в переменной то же самое передавать?). При трансляции программы возможно много узких мест, например, конфликт банков DRAM, пенальти (замедление кода в десятки раз). Ты в курсе о чем я? Все это разруливается оптимальным размещением блоков памяти и команд. Вот это и есть узкое место. Ты его просто не там ищешь.
354 Elkmor
 
08.02.07
14:49
да, для оптимизации алгоритмов конечно лучше процедурный

но где они - эти алгоритмы? редки, как и ассемблер

применяются в узкоспециализированных местах

основная масса программ - по передаче/хранению/конвертированию данных, быстродействие которых просто не лечится переводом на процедурный язык, потому что ООП удовлетворяет полностью. даже в хитрозадой трехмерной графике все предпочитают пользоваться объектами, лишь некоторые библиотеки используют структуры из-за соображений совместимости с языком С...
355 Elkmor
 
08.02.07
14:50
(354) + это я так, не в тему... :)
359 NS
 
08.02.07
14:57
(353) Ты написал просто набор бессвязных слов. Почитай что нписал я, и попробуй применить ООП хотя бы в самой маленькой процедуре завязанной на доску.



 Что сказал Орефков,  я отлично понял.
Этот недоумок, знаток оперативного учета - просто возомнил себя крутым профи, а в итоге показал что он просто моська.
360 romix
 
модератор
08.02.07
14:57
(356) Имхо ты не прав, они могут быть либо правы, либо добросовестно заблуждаться, наезды типа "придурок" тут неуместны.
Предлагаю закрыть ветку, продолжить через нек. время в новой.
Зацени плиз статью, там по теме (я ее имею в виду).
Книга знаний: Трансляция объектов в машинный код в Delphi
361 NS
 
08.02.07
14:58
(355) Ты видел пост Орефкова?
362 NS
 
08.02.07
14:58
(360) Я предлагаю не закрывать ветку, тем более ответить на наезд недоумка Орефкова - я просто обязан.
Таких неучей как он еще поискать надо.
363 NS
 
08.02.07
15:01
(360) Если Орефков имеет право писать сто-либо по поводу моей квалификации, квалификация Хьятта, квалификации ведущих разработчиков трансляторов и процессоров которые используют тектс Хьятта в виде теста - что о нем еще можно сказать? Хьятт говорит тоже самое - от примененияООП в шахматной программе - трехкратное падение производительности.

Так кто же такой Орефков? Насколько он умен?
364 romix
 
модератор
08.02.07
15:02
(361) Если ты меня спрашиваешь - 355 не мой пост - то видел.
В (353) я написал что он возможно имел в виду.