Да, но набор логических операций, насколько бы сложными они не были, всё равно быстрее, чем те же операции и несколько циклов в придачу. И не факт, что писанины меньше.
Либо, учесть, что по умолчанию все выравнивается по двойному слову, а промежутки заполняются нулями, то есть при сравнении через memcpy они не учитываются.
Просто этот «очевидный способ» занимает одну строку, пишется легко и не имеет проблем с производительностью.
хм, обычно если в структуре много полей то имеет смысл создать что-то вроде
std::map<std::string, Something>
а тогда такие вопросы решаются сами собой.
И кроме того редко встречал ситуации когда стравнение шло по многим параметрам — обычно достаточно сравнить по одному ( ну двум ) ключевому чтобы точно сказать равно, больше или меньше
хм, ну вместо создания отдельных переменных мы храним данные в мэпе. Таким образом сравнение, обнуление — все это делается простейшими циклами
std::for_each
std::equal
если данные однородные — то можно хранить в мэпе сразу нужный тип данных. Если разных типов — то либо через базовый класс, либо можно хранить все в строках, и автоматически преобразовывать
скажем так
bool get(const std::string& key, T& t)
{
istringstream istr(map[key]);
istr >> t;
return istr.good();
}
не хранить таким образном переменные циклов, а хранить лишь обычные данные.
вообще из привычного — если нужно хранить множество однородных данных — то это
— данные конфига ( нужно лишь изредка читать — производительность не страдает даже если каждый раз читать из файла )
— сохраненный файл данных — раз вычитал и забыл — или раз записал и забыл
как бы то ни было — не те вещи с которыми нужно постоянно работать. Производительность вообще странная штука — иногда думаешь как бы оптимизировать а потом передаешь файл по сети пару секунд — и все остальные оптимизации делаются ненужными =)
Ну, если Вам интересно порыться в boost и поизучать разные программерские финты — то это хороший пример. Но упаси Вас Бог так писать в реальной программе. На это есть как минимум 2 причины:
1. Никто, кроме Вас, в жизни не поймет что тут написано. Нет, ну если человек порассматривает код, подумает пару минут, поднимет мануал по незнакомым ему частям буста, пройдетя в дебаггере — то да. Но на практике быстрее и проще выгнать из команды человека, пишущего такой код, чем на каждые его 2 строчки тратить по 10 минут время на попытки понять в чем суть.
2. Сделайте массив на 10 000 рандомных структур и заюзайте для него какую нибудь сортировку, вызывающую оператор<. Замеряйте время при классической реализации и при Вашей. Мне кажется, разница будет существенна (конечно же, в пользу классической).
Вывод: если можно написать понятный и быстро работающий код, то не нужно писать непонятный и медленно работающий, даже если он будет на пару строк короче.
Проверил.
Классический способ быстрее, как и ожидалось, время около 2.8с. «Хороший» и «безумный» способы примерно равноценны, время около 3.7с, но «безумный» обычно быстрее на 0.01с.
От количества полей (2, 3, 4) зависит незначительно.
Структура из интов, размер массива 10 000 000 элементов, сортировка std::sort, данные в каждом подходе одинаковые, компилятор VS2008, Release.
Это не совсем корректная проверка, потому как похоже что основную часть времени будет занимать не код сравнения, а код сортировки, вызова функций, и так далее.
Попробуйте просто в цикле на несколько миллионов раз вызвать для разных структур оператор.
Вполне корректная, я считаю. Доля прочего кода при одних и тех же данных постоянна, меняется лишь время сравнения. Точное отношение скоростей сравнения проверка не даст, но выявить победителя позволит точно.
И потом, где еще используется такое массовое сравнение? Обычно при сортировке и поиске.
Времена 10 000 000 сравнений, с:
0.168, 0.232, 0.233
Что подтверждает.
[C++] Сравнение структур по набору полей