Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[18.220.64.128] |
|
Сообщ.
#1
,
|
|
|
Что лучше с точки зрения производительности и вообще?
И кстати есть ли BOOL в никсовых компиляторах? |
Сообщ.
#2
,
|
|
|
Цитата RomanTTT @ Конечно есть. Более того, есть в любом компиляторе C/C++ И кстати есть ли BOOL в никсовых компиляторах? typedef int BOOL; Добавлено Цитата RomanTTT @ А сам поэкспериментировать не пробовал? Что лучше с точки зрения производительности и вообще? |
Сообщ.
#3
,
|
|
|
Цитата Что лучше с точки зрения производительности Не в том месте ты бутылочное горло ищешь |
Сообщ.
#4
,
|
|
|
Граждане, объясните для неСи-шников, в чём разница?
|
Сообщ.
#5
,
|
|
|
Цитата Граждане, объясните для неСи-шников, в чём разница? bool - специфицирован в Стандарте. sizeof(bool) = 1 (см. Стандарт C++ 2003 года). BOOL - есть в WinAPI. Но ничего не мешает его сделать где угодно ещё. sizeof(BOOL) = 4. +доп. фишки: на std::vector<bool> в STL есть очень модная и быстрая специализация, которой нету для std::vector<BOOL>. Но это всё - мелочи жизни, если разобраться. |
Сообщ.
#6
,
|
|
|
Цитата trainer @ Цитата RomanTTT @ Конечно есть. Более того, есть в любом компиляторе C/C++ И кстати есть ли BOOL в никсовых компиляторах? typedef int BOOL; А почему прямо так в любом и везде int? Это какая-то негласная договоренность? Ведь в стандарте нет никакого BOOL |
Сообщ.
#7
,
|
|
|
Наверное, он имел в виду, что "если в каких то отсталых компиляторах его нету, то его будет несложно сварить самому из топора и сапога, добавив в варево немножко кирпичей".
Добавлено (а вот, например, тот же тип CHAR использовать не рекомендуется) Добавлено (так же как и тип INT - нету WinAPI функций, в которых использование их было бы обосновано). |
Сообщ.
#8
,
|
|
|
Цитата trainer @ А сам поэкспериментировать не пробовал? Получается bool эффективнее. Вот тестовая прога void main() { clock_t start, finish; double diffTime = 0.0f; double duration; BOOL* b1 = new BOOL[50000000]; start = clock(); for(ULONG i = 0; i < 50000000; ++i) { b1[i] = FALSE; if(!b1[i]) b1[i] = TRUE; } finish = clock(); delete[] b1; duration = (double)(finish - start) / CLOCKS_PER_SEC; printf("Time for BOOL is %2.2f seconds\n", duration); //////////////////////////////////////////////////// bool* b2 = new bool[50000000]; start = clock(); for(ULONG i = 0; i < 50000000; ++i) { b2[i] = false; if(!b2[i]) b2[i] = true; } finish = clock(); delete[] b2; duration = (double)(finish - start) / CLOCKS_PER_SEC; printf("Time for bool is %2.2f seconds\n", duration); getch(); } в релизе для bool 0.11, для BOOL 0.41 в дебаге разница меньше, но тоже в пользу bool |
Сообщ.
#9
,
|
|
|
Ну, примерно этого и следовало ожидать.
Цитата в релизе для bool 0.11, для BOOL 0.41 как раз примерно в 4 раза = sizeof(BOOL)/sizeof( bool ) |
Сообщ.
#10
,
|
|
|
А ведь машинное слово вроде 2 байта. Я думал память читается сразу словами, поэтому как раз не ожидал большого преимущества у bool.
Или работа с памятью идет через отдельные байты, а не слова? |
Сообщ.
#11
,
|
|
|
Ну, этим тестом ты скорее доступ к куче тестировал
Которая в случае с BOOL получилась в 4 раза больше. А так же возможно (я не знаю, сколько у тебя оперативы) своп (а то, что 10000 Кб из памяти считаем быстрее, чем 40000 Кб - это очевидно) |
Сообщ.
#12
,
|
|
|
Цитата RomanTTT @ Не нравится int - напиши char.А почему прямо так в любом и везде int? Цитата BugHunter @ Точно? В варианте 1998 года:sizeof(bool) = 1 Цитата Note: in particular, sizeof(bool) and sizeof(wchar_t) are implementation-defined69) ... 69) sizeof(bool) is not required to be 1 |
Сообщ.
#13
,
|
|
|
double Так и должно подсвечивать? |
Сообщ.
#14
,
|
|
|
Цитата trainer @ Цитата Note: in particular, 69) sizeof(bool) is not required to be 1 и в 2003 так -Added Цитата trainer @ Не нравится int - напиши char. Мне вообще BOOL не нравится. Поскольку мы в холиварах я за bool |
Сообщ.
#15
,
|
|
|
Цитата Точно? В варианте 1998 года.. Точно. В 2003. (счазз найду точную цитату..) |
Сообщ.
#16
,
|
|
|
Цитата B.V. @ Обсуждалось уже. Это глюкобаг. Так и должно подсвечивать? Добавлено Цитата BugHunter @ И шифр документа заодно. В 2003. (счазз найду точную цитату..) Добавлено Я имею в виду ISO/IEC 14882 и далее |
Сообщ.
#17
,
|
|
|
Цитата BugHunter @ Точно. В 2003. (счазз найду точную цитату..) Дык я уже нашел в 2003, там тоже самое: "sizeof(bool) is not required to be 1." В параграфе 5.3.3 |
Сообщ.
#18
,
|
|
|
Мдяя........ точно!
Откуда же я тогда взял, что sizeof(bool) = 1? точно где то ведь читал, в пожеланиях к Стандарту что ли?... |
Сообщ.
#19
,
|
|
|
Цитата RomanTTT @ Что лучше с точки зрения производительности и вообще? И кстати есть ли BOOL в никсовых компиляторах? 1. BOOL --- злостный макрос, что само по себе должно настораживать. 2. BOOL --- это не тип, а имя типа, поэтому для него нельзя перегрузку (так же как и для некоторых случаев с TCHAR). 3. Более строгая типизация. В общем, однозначно bool. Цитата RomanTTT @ А ведь машинное слово вроде 2 байта. Кто это сказал? На IA-32 машинное слово 4 байта, на x86-64 и IA-64 --- 8 байт. |
Сообщ.
#20
,
|
|
|
Цитата BugHunter @ Видимо, из MSDN Откуда же я тогда взял, что sizeof(bool) = 1? Цитата In Visual C++4.2, the Standard C++ header files contained a typedef that equated bool with int. In Visual C++ 5.0 and later, bool is implemented as a built-in type with a size of 1 byte. That means that for Visual C++ 4.2, a call of sizeof(bool) yields 4, while in Visual C++ 5.0 and later, the same call yields 1. |
Сообщ.
#21
,
|
|
|
Даешь холивар "буквы алфавита разных регистров друг против друга"!
|
Сообщ.
#22
,
|
|
|
Цитата trainer @ Обсуждалось уже. Это глюкобаг. И это неисправимо? |
Сообщ.
#23
,
|
|
|
Цитата B.V. @ Говорят, исправимо. Но не сейчас. И это неисправимо? |
Сообщ.
#24
,
|
|
|
Цитата Relan @ Даешь холивар "буквы алфавита разных регистров друг против друга"! Не надо утрировать. Причем тут регистр? Скорее уж "макросы против встроенных типов" |
Сообщ.
#25
,
|
|
|
Цитата RomanTTT @ Во-первых, BOOL в более-менее свежем Microsoft Windows Platform SDK не макрос, а typedef. Во-вторых, в старых компиляторах bool может быть также не встроенным типом, а typedef'ом. Смотри цитату выше из MSDN. Скорее уж "макросы против встроенных типов" |
Сообщ.
#26
,
|
|
|
А кстати, в 2005 студии wchar_t таки стал встроенным типо по умолчанию, или же опять таки придётся эту опцию компилятора (/Zc:wchar_t) включать?
|
Сообщ.
#27
,
|
|
|
Народ, вам предлагается сравнивать мягкое с теплым. А именно полноценный тип (bool) с синонимом другого типа (BOOL). Все точки над ё в этом вопросе расставил Саттер в своих "Новых сложных задачах", где с разных сторон рассмотрел именно этот вопрос.
|
Сообщ.
#28
,
|
|
|
Цитата Flex Ferrum @ Народ, вам предлагается сравнивать мягкое с теплым. А именно полноценный тип (bool) с синонимом другого типа (BOOL). Все точки над ё в этом вопросе расставил Саттер в своих "Новых сложных задачах", где с разных сторон рассмотрел именно этот вопрос. С точки зрения языка - да. А с точки зрения практики - нет, потому что предмет может быть одновременно мягким и теплым, а переменная не может быть одновременно BOOL и bool. Когда нужна логическая переменная, то приходится выбирать между ними. В этом холивар и заключается (хотя не спорю, что не такой уж он холиваристый ) Насчет Саттера - спасибо за подсказку, гляну -Added Цитата trainer @ Цитата RomanTTT @ Во-первых, BOOL в более-менее свежем Microsoft Windows Platform SDK не макрос, а typedef.Скорее уж "макросы против встроенных типов" Да, сорри, опечатался. Хотя макросы по-любому тоже задействованы (в лице TRUE и FALSE) |
Сообщ.
#29
,
|
|
|
Цитата RomanTTT @ А с точки зрения практики - нет, потому что предмет может быть одновременно мягким и теплым, а переменная не может быть одновременно BOOL и bool. С точки зрения практики различие тоже существенное. Ты, например, не можешь сделать отдельную (отличную от int'а) специализацию шаблона для BOOL, но легко для bool. |
Сообщ.
#30
,
|
|
|
Цитата BugHunter @ А кстати, в 2005 студии wchar_t таки стал встроенным типо по умолчанию, или же опять таки придётся эту опцию компилятора (/Zc:wchar_t) включать? AFAIK, wchar_t стал встроенным. Цитата RomanTTT @ А с точки зрения практики - нет, потому что предмет может быть одновременно мягким и теплым, а переменная не может быть одновременно BOOL и bool. Когда нужна логическая переменная, то приходится выбирать между ними. В этом холивар и заключается (хотя не спорю, что не такой уж он холиваристый ) С точки зрения практики: void f(BOOL a){} void f(int a){} void f(char a){} void f(signed char a){} void f(unsigned char a){} void f(short a){} void f(unsigned short a){} void f(unsigned int a){} Вопрос: скомпилируется или нет? |
Сообщ.
#31
,
|
|
|
Цитата mo3r @ Вопрос: скомпилируется или нет? Ну и что из того, что не скомпилируется? Все равно (как я уже говорил) когда нужна логическая переменная, то приходится выбирать между BOOL и bool. В этом и весь вопрос. -Added Цитата Flex Ferrum @ С точки зрения практики различие тоже существенное. Ты, например, не можешь сделать отдельную (отличную от int'а) специализацию шаблона для BOOL, но легко для bool. Ну естественно есть разница. Если бы не было разницы, то bool и BOOL были бы эквивалентны Я не говорил, что разницы нет, я только имел в виду, что сравнение с теплым и мягким было некорректным. |
Сообщ.
#32
,
|
|
|
Цитата RomanTTT @ когда нужна логическая переменная, то приходится выбирать между BOOL и bool. В этом и весь вопрос. Ээээ... Когда нужна логическая переменная - то выбор то как раз однозначный. А именно - bool. Потому как BOOL не ведет себя как логическая переменная, а только в некоторых аспектах подражает ее поведению. |
Сообщ.
#33
,
|
|
|
Кажется холивар "bool vs BOOL" плавно переходит в холивар "холивар это или не холивар"
-Added Цитата Flex Ferrum @ Потому как BOOL не ведет себя как логическая переменная, а только в некоторых аспектах подражает ее поведению. Но используется-то она как логическая! |
Сообщ.
#34
,
|
|
|
Цитата RomanTTT @ Но используется-то она как логическая! Ну, микроскоп тоже можно в качестве молотка использовать... Но это не значит, что микроскоп - это молоток... Добавлено RomanTTT, вообще есть только один случай, когда можно предпочесть BOOL bool'у. И этот случай связан с производительностью. Но и тут все зависит от того, какие sizeof(bool) и sizeof(BOOL). Если sizeof(BOOL) - 4, а bool'а - 1, то в ряде алгоритмов, чувствительных к скорости выполнения, на работу с bool'ом будет тратится больше времени за счет того, что 1 байт из памяти вытащить (в общем случае) дольше, чем 4-ре, а при заргрузке этого значения в 32-битный регистр должно произвойти расширение до 4-х байт, что тоже требует времени. Т. е. машинная арифметика оперирует машинными словами быстрее, чем одиночными байтами. Но такие случаи (когда эта разница действительно играет существенную роль), вообще говоря, редки. |
Сообщ.
#35
,
|
|
|
Цитата Flex Ferrum @ вообще есть только один случай, когда можно предпочесть BOOL bool'у. И этот случай связан с производительностью. Но и тут все зависит от того, какие sizeof(bool) и sizeof(BOOL). Если sizeof(BOOL) - 4, а bool'а - 1, то в ряде алгоритмов, чувствительных к скорости выполнения, на работу с bool'ом будет тратится больше времени за счет того, что 1 байт из памяти вытащить (в общем случае) дольше, чем 4-ре, а при заргрузке этого значения в 32-битный регистр должно произвойти расширение до 4-х байт, что тоже требует времени. Т. е. машинная арифметика оперирует машинными словами быстрее, чем одиночными байтами. Хм, а почему в моем вышеприведенном тесте bool было производительнее? Или в куче производительнее bool, а в стеке BOOL? |
Сообщ.
#36
,
|
|
|
Цитата RomanTTT @ Видимо потому, что массив требует меньше памяти в 4 раза. Выделение памяти - тоже затратная операция. Нужно найти блок размером не меньше запрошенного. Чем меньше блок - тем быстрее будет найдено место под него. а почему в моем вышеприведенном тесте bool было производительнее? |
Сообщ.
#37
,
|
|
|
Выделение блока - это new?
new не могло повлиять. Я сначала делал new, а потом засекал стартовое время и начинал работу с массивом. Так что на результат влияла только скорость доступа к переменным. (напоминаю, что код теста на первой странице темы) |
Сообщ.
#38
,
|
|
|
Цитата RomanTTT @ Выделение блока - это new? new не могло повлиять. Я сначала делал new, а потом засекал стартовое время и начинал работу с массивом. Так что на результат влияла только скорость доступа к переменным. (напоминаю, что код теста на первой странице темы) Мог повлиять. Могли сказаться механизмы виртуальной памяти (например, выделение физической памяти может происходить не сразу, а по мере необходимости). |
Сообщ.
#39
,
|
|
|
Цитата Но используется-то она как логическая! кем используется?. Она действительно оправдана при использовании WinAPI функций, у которых аргументы/возвращаемые значения BOOL (смысла маскировать происходящее не вижу). Случаи описанные Flex_Ferrum-ом редки, но есть. Но всё тки bottle neck обычно всё таки в других местах находится. Цитата Могли сказаться механизмы виртуальной памяти Это врят ли - память выделяется сразу, если в VirtualAlloc явно не задать флаг RESERVE. Думаю, что это можно легко проверить усыпив процесс на минуту перед запуском основного измерения, например, и глянув в Task Manager. Уверен, что в данном тесте эти эффекты не сказались. ....попробовал. Всё в порядке. У меня выделяется сразу. Разница в производительности как и полагается - в 4 раза. +)можно добавить что на некоторых платформах sizeof(bool*) > sizeof(int*) (например, 6 и 4 соответственно), поэтому если нужно хранить указатели, то действительно лучше не морочиться и использовать int, а ещё лучше - DWORD, что бы явно указать, сколько ИМЕННО байт ты хотел бы там увидеть. Добавлено А вот интересные результаты из Linux. Time for BOOL 2.83 Time for bool 2.37 это становится интересным. Добавлено Под Win попробовал поменять компилятор. Взял gcc. давайте сравним: gcc Time for BOOL 15.38 second Time for bool 1.67 second MSVC++ Time for BOOL 5.51 second Time for bool 1.43 second Добавлено короче, я не знаю что именно измеряет этот тест, но то что bool получается эффективнее - налицо Добавлено машина (железка) та же самая. кроме того в Lin загрузка памяти больше (один только x-server сколько отжирает собака) Добавлено это ещё кстати, хорошая иллюстрация "безумной" эффективности линуха, и пророка его - gcc. |
Сообщ.
#40
,
|
|
|
Цитата BugHunter @ это ещё кстати, хорошая иллюстрация "безумной" эффективности линуха, и пророка его - gcc. Версию gcc, а также строку компиляции --- в студию. |
Сообщ.
#41
,
|
|
|
я думаю, make файл ответит на твои вопросы:
(особо я не заморачаивался с ним, если честно). Цитата CPP = g++ CC = gcc RES = OBJ = main.o $(RES) LINKOBJ = main.o $(RES) LIBS = -L"/usr/lib" INCS = -I"/usr/include/c++/4.0.2/" CXXINCS = -I"/usr/include/" -I"/usr/include/c++/4.0.2" BIN = booltest.bin CXXFLAGS = $(CXXINCS) CFLAGS = $(INCS) RM = rm -f .PHONY: all all-before all-after clean clean-custom all: all-before booltest.bin all-after clean: clean-custom ${RM} $(OBJ) $(BIN) $(BIN): $(OBJ) $(CPP) $(LINKOBJ) -o "booltest.bin" $(LIBS) main.o: main.cpp $(CPP) -c -o3 main.cpp -o main.o $(CXXFLAGS) Добавлено в win кстати версия gcc младше: 3.4.2. |
Сообщ.
#42
,
|
|
|
4.0.2? В 4.0.x большие проблемы с оптимизацией (в этой ветке осуществлялась смена архитектуры компилятора, поэтому оптимизация была в не совсем хорошем состоянии), поэтому сравнивать надо с 4.1.x.
Цитата BugHunter @ в win кстати версия gcc младше: 3.4.2. Этим и объясняется разница у gcc под windows и linux. |
Сообщ.
#43
,
|
|
|
не пинял как младший бул выиграл у тебя.. я в код не вчитывался.. но наверно у тебя там какието приведения типа для BOOL
BOOL func (BOOL a) { for (int i = 0; i < 1000000000; ++i) a = a || (rand() + 77) / 500; return a; } bool func1 (bool a) { for (int i = 0; i < 1000000000; ++i) a = a || (rand() + 77) / 500; return a; } int main() { int tm = time (0); func (TRUE); std::cout << time(0) - tm; tm = time (0); func1 (true); std::cout << time(0) - tm; } Показали одинаковый результат. видимо компилятор просто оптимизирует bool - и работая с ней как с 4 байтовым значением т.к. char func1 (char a) { for (int i = 0; i < 1000000000; ++i) a = a || (rand() + 77) / 500; return a; } показывает зужший результат чем BOOL а всеже тоже 1 байт.. таже орифметика. Добавлено но в качестве логического значение только неоюходимость пользовать WinAPI может заставить пользовать BOOL. |
Сообщ.
#44
,
|
|
|
Цитата LuckLess @ Показали одинаковый результат что то мне кажется, что большая часть времени у тя тратится на генерацию случайного числа rand() |
Сообщ.
#45
,
|
|
|
Цитата jack128 @ что то мне кажется, что большая часть времени у тя тратится на генерацию случайного числа rand() BOOL func (BOOL a) { int rnd = rand(); for (int i = 0; i < 3000000000; ++i) a = a || rnd + (a*8 - rnd/155) + 192; return a; } bool func1 (bool a) { int rnd = rand(); for (int i = 0; i < 3000000000; ++i) a = a || rnd + (a*8 - rnd/155) + 192; return a; } int main() { int tm = GetTickCount (); func (TRUE); std::cout << GetTickCount () - tm << "\n"; tm = GetTickCount (); func1 (true); std::cout << GetTickCount () - tm; } результат одинаковый в пределах погрешности(+-30мс). |
Сообщ.
#46
,
|
|
|
Помню я на форуме С++ создавал тему про ошибку. Создал консолньый проект, там сделал класс, перенес код в ГУИ, а там все заглючило.
Ошибка была вот в чем: typedef char BOOL; // в консольном проекте не подключал windows.h он был не нужен Когда я узнал, что Microsoft сделал BOOL int'ом - я был в шоке. За такое разработчиков надо кастрировать или оторвать пальцы. |
Сообщ.
#47
,
|
|
|
Цитата Red Devil @ Когда я узнал, что Microsoft сделал BOOL int'ом - я был в шоке. За такое разработчиков надо кастрировать или оторвать пальцы. Это из-за размера? Тогда огорчу, 1-байтная переменная на современных 32-битных процессорах ведет к уменьшению производительности. |
Сообщ.
#48
,
|
|
|
Цитата Когда я узнал, что Microsoft сделал BOOL int'ом - я был в шоке. За такое разработчиков надо кастрировать или оторвать пальцы. Вообще то размер bool Стандартом не специфицирован, поэтому мы имеем то что имеем. Каждый производитель компиляторов волен тут делать всё, что захочет, поэтому - без фанатизма пожалуйста. Цитата Это из-за размера? Тогда огорчу, 1-байтная переменная на современных 32-битных процессорах ведет к уменьшению производительности. ну да, если не рассматривать такой момент, что этот самый int ещё и хранить где то нужно (ну, давайте к примеру сравним объёмы 1000000 int-ов и bool ), то быстрее . Если рассматривать ТОЛЬКО обращение к переменной - то быстрее. +компиль на самом деле может так хитро съоптимизировать, что никаких переменных создаваться вообще не будет, так что не знаю, не знаю... мне bool вообще приятнее. |
Сообщ.
#49
,
|
|
|
Цитата BugHunter @ так что не знаю, не знаю... мне bool вообще приятнее. но если он станет 4-х байтным, то я не огорчусь. приятней он мне т.к. он стандартный |
Сообщ.
#50
,
|
|
|
Странно, что вы высчитываете байты... помоему самая большая проблема в выборе между BOOL и bool:
int IsObjectValid() { return -1; // Например Object is invalid! } BOOL IsValid() { return IsObjectValid(); } int main() { if( IsValid() == TRUE ) .... // Ошибка } |
Сообщ.
#51
,
|
|
|
Цитата MOHAX @ Странно, что вы высчитываете байты... помоему самая большая проблема в выборе между BOOL и bool: А в чем ты тут видишь проблему? |
Сообщ.
#52
,
|
|
|
Цитата MOHAX @ Эта проблема называется "использование магических чисел" и "неявные преобразования". помоему самая большая проблема в выборе между BOOL и bool |
Сообщ.
#53
,
|
|
|
Нельзя сравнивать переменную типа BOOL со значениями TRUE и FALSE.
Т.е. как в приведенном выше примере: if( IsValid() == TRUE ) { // Этот код никогда не выполнится } if( IsValid() == FALSE ) { // И этот код тоже никогда не выполнится } Именно поэтому я за bool |
Сообщ.
#54
,
|
|
|
Почему не выполнится
if( IsValid() == FALSE ) { } понятно, потому что FALSE на самом деле это 0. Как правильно заметил Трейнер, это всего лишь проблема использования магических констант. Проблема легко лечится битием по рукам: если магическая константа не равно 0, то её необходимо тчательно документировать (и бить по рукам того, кто это не делает) |