Здравствуйте, Lazin, Вы писали:
L>По поводу сишечки — я вот например иногда использую т.н. structure hack, для производительности, в c++ коде. Может ты сумеешь предложить типобезопасный аналог на шаблона, раз уж ты такой их фанат?
А в чём беда-то?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Erop, Вы писали:
L>>А можно просто проверять размер массива, прежде чем делать reinterpret_cast E>А зачем его вообще делать?..
Изначальный пример состоял в следующем — у нас есть отмаппленый в память файл, который разбит на страницы, работа с данными страниц происходит через структуру:
struct Page {
int len;
...some metadata...
int offsets[];
};
мы берем указатель на начало страницы, делаем reinterpret_cast<Page*> и работаем со страницей как с обычной структурой. Все клево и просто. Можно делать placement new, если нужно чтобы был вызван конструктор, в который можно например передать len и метаданные. Я предложил сделать это на С++, ибо все плюются от "Си кода в программе на С++"
Вообще, оффтопик изначально начался с того, что кое кто высказался на тему того, что код на "современном С++" имеет тенденцию переусложнять простые вещи. Вот и этот пример со struct hack на Си выглядит значительно проще и понятней чем все предложенные варианты на правильном современном С++.
E>Если элементы массива POD, то можно прямо как в С сделать же, тока для безопасности лучше таки new с delete переделать. E>А если не POD, то всё равно их создавать/разрушать надо, то есть опять же new и delete надо прятать, а создавать/разрушать фабричными методами какими-то...
Какие еще фабрики? Мы же говорим о моем примере, или уже говорим в общем?
L>>Вот в том то и дело, что человеку, применяющему struct hack в коде ничего такого не хочется, скорее наоборот, "сервисы как в С++" для него выглядят как переусложнение кода E>В смысле "не хочется"? Ну, например, получить доступ к массиву как к паре интераторов может же захотеться? А обратный итератор, например?..
Когда мне потребовалось использовать вот это вот в коде одного проекта, мне нужно было дописывать элементы в массив, сортировать их и перебирать по порядку. Reverse iterator в принципе и здесь реализуем без всяких наворотов, только вот взялся этот reverse iterator не из условий задачи, в этом то и проблема
Здравствуйте, Lazin, Вы писали:
L>мы берем указатель на начало страницы, делаем reinterpret_cast<Page*> и работаем со страницей как с обычной структурой. Все клево и просто. Можно делать placement new, если нужно чтобы был вызван конструктор, в который можно например передать len и метаданные. Я предложил сделать это на С++, ибо все плюются от "Си кода в программе на С++"
Ну так в чём проблема сделать тоже самое, но на С++ и типобезопасно?
L>Вообще, оффтопик изначально начался с того, что кое кто высказался на тему того, что код на "современном С++" имеет тенденцию переусложнять простые вещи.
Скорее это свойство не С++, а плохих инженеров...
L>Вот и этот пример со struct hack на Си выглядит значительно проще и понятней чем все предложенные варианты на правильном современном С++.
Ну положим мы не будем обсуждать как написать шаблон, а будем писать ту же структуру, но на С++ и безопасную.
Как будем писать?
1) Добавим методы типа operator[] такой и сякой.
2) Добавим методы/функции формирования/создания
3) Запретим неправильные пути создания и разрушения
E>>Если элементы массива POD, то можно прямо как в С сделать же, тока для безопасности лучше таки new с delete переделать. E>>А если не POD, то всё равно их создавать/разрушать надо, то есть опять же new и delete надо прятать, а создавать/разрушать фабричными методами какими-то... L>Какие еще фабрики? Мы же говорим о моем примере, или уже говорим в общем?
Не фабрики, а фабричные методы, например они могут и в переданном буфере создавать объект...
L>Когда мне потребовалось использовать вот это вот в коде одного проекта, мне нужно было дописывать элементы в массив, сортировать их и перебирать по порядку. Reverse iterator в принципе и здесь реализуем без всяких наворотов, только вот взялся этот reverse iterator не из условий задачи, в этом то и проблема
Ну я про это и говорил, что если надо, можно дописать...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
SD>vector<tuple<int, string>> results;
SD>db_pool.query("SELECT id, name FROM accounts WHERE date>?", results, last_login_date);
SD>for (auto account : results)
SD> cout << get<1>(account) << endl;
SD>
SD>Для чего нужно CRC32? Для поддержки prepared statements, которые привязаны к соединениям. Поскольку соединений в пуле много, неизвестно, поступал ли уже этот запрос в это соединение или нет. Если поступал, то по CRC32 запроса можно его найти. Вероятность коллизии крайне мала, запросов же не сотни тысяч.
SD>Можно делать иначе — в рантайме регистрировать каждый запрос, на стартапе получать уникальный ID, и пользовать его. Решение с CRC32 банально быстрее было написать, и меньше тестировать.
Можно сделать в лоб — считать crc32 при каждом вызове db_pool.query. С учетом скорости вычисления crc32 и того, что исполнение запроса — обычно tcp\ip, то "банально быстрее" убирает пару десятков мкс из пары десятков мс, что обычно ни о чем...
Здравствуйте, Lazin, Вы писали:
L>APR умеет vectorised I/O, boost нет, apr может в базы данных(и даже умеет prepare), boost нет. По поводу сишечки — я вот например иногда использую т.н. structure hack, для производительности, в c++ коде. Может ты сумеешь предложить типобезопасный аналог на шаблона, раз уж ты такой их фанат?
Я давненько ничего не писал на плюсах, хочу уточнить: целочисленные параметры на шаблонах уже отменили?
S>Всё типобезопасненько. Ни один верификатор не подкопается.
Увы, n неизвестно на этапе компиляции, даже размер страницы неизвестен. Это пример из практики, там данные в страницу записываются с конца, а смещения этих данных добавляются в массив offsets. И так до тех пор, пока в странице есть место.
Здравствуйте, Erop, Вы писали:
E>Здравствуйте, Lazin, Вы писали:
L>>мы берем указатель на начало страницы, делаем reinterpret_cast<Page*> и работаем со страницей как с обычной структурой. Все клево и просто. Можно делать placement new, если нужно чтобы был вызван конструктор, в который можно например передать len и метаданные. Я предложил сделать это на С++, ибо все плюются от "Си кода в программе на С++"
E>Ну так в чём проблема сделать тоже самое, но на С++ и типобезопасно?
Я не вижу способа сделать это действительно безопасным. Ну то есть можно кое что предпринять на этапе компиляции, но все равно нужны runtime проверки.
L>>Вообще, оффтопик изначально начался с того, что кое кто высказался на тему того, что код на "современном С++" имеет тенденцию переусложнять простые вещи. E>Скорее это свойство не С++, а плохих инженеров...
Возможно. А возможно это дает о себе знать культура, сложившаяся в сообществе С++ программистов
L>>Вот и этот пример со struct hack на Си выглядит значительно проще и понятней чем все предложенные варианты на правильном современном С++.
E>Ну положим мы не будем обсуждать как написать шаблон, а будем писать ту же структуру, но на С++ и безопасную. E>Как будем писать?
E>1) Добавим методы типа operator[] такой и сякой. E>2) Добавим методы/функции формирования/создания E>3) Запретим неправильные пути создания и разрушения
Мой метод, определить это все безобразие внутри срр файла и использовать только в нем. И ничего не придется ограничивать
Здравствуйте, Lazin, Вы писали:
L>Увы, n неизвестно на этапе компиляции, даже размер страницы неизвестен. Это пример из практики, там данные в страницу записываются с конца, а смещения этих данных добавляются в массив offsets. И так до тех пор, пока в странице есть место.
Ну, во-первых, тогда вы говорите о struct hack второго порядка.
Потому что классический struct hack — это фиксированный заголовок и "плавающий" хвост. И с ним в C++ всё в порядке.
Для того, чтобы получить типобезопасность, нужно понимать, что вы называете типобезопасностью.
От каких именно ошибок должен вас застраховать компилятор? От выхода за границы страницы? Невозможно — вы же до рантайма ничего не знаете о структуре страницы.
Вся разница между С и С++ в возможности обеспечить инкапсуляцию.
На С++ я опишу страницу совершенно обычным объектом, где сначала идут фиксированные поля заголовка, затем "гибкий" список смещений записей, а потом уже данные записей. А целостность я гарантирую при помощи методов типа
Здравствуйте, Lazin, Вы писали:
E>>Ну так в чём проблема сделать тоже самое, но на С++ и типобезопасно? L>Я не вижу способа сделать это действительно безопасным. Ну то есть можно кое что предпринять на этапе компиляции, но все равно нужны runtime проверки.
Вся небезопасность сосредоточена в корректной интерпретации. На C++ это делается при помощи класса указателя PageRef, который инкапсулирует всю логику — в частности, проверяет что его нельзя сконструировать из неверно выравненного указателя, а также что по указанному адресу лежит действительно валидная страница.
С этого момента все операции со страницей гарантированно корректны, т.к. все reinterpret_cast спрятаны внутрь безопасных методов, типа page->records[2]->fields[3]->AsInt64(), и производительностью, эквивалентной c-style записи того же самого.
L>>>Вот и этот пример со struct hack на Си выглядит значительно проще и понятней чем все предложенные варианты на правильном современном С++.
У меня сложилось впечатление, что собственно Си вы не застали. "на Си" предложенный вами хак — это минное поле, где шаг вправо-влево приводит в лучшем случае к access violation, а в худшем — к потере данных. На всякий случай напомню, что никакой инкапсуляции в С нет, так что если вы где-то в прикладном коде забыли assert, то вы запросто угробите всю вашу страницу в момент обращения к соседней.
L>Мой метод, определить это все безобразие внутри срр файла и использовать только в нем. И ничего не придется ограничивать
Вы описываете решение на С++, а не на C.
В абстрактно-общем случае ничего более полезного, чем описанная инкапсуляция, получить не удастся. Т.е. у вас будет минимальная гарантия — при ошибке в прикладном коде у вас будет не загадочная потеря данных, а внятное исключение. Это уже огромный прогресс по сравнению с С, где вся инкапсуляция построена на передаче void*, и никак не защищает от перепутывания указателя на запись с указателем на страницу.
В более специфичном случае, к примеру, если известны структуры хранимых записей, можно сделать вообще полностью типобезопасную обёртку, которая статически будет вам гарантировать отсутствие в рантайме вещей типа record index out of bounds.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Lazin, Вы писали:
L>Я не вижу способа сделать это действительно безопасным. Ну то есть можно кое что предпринять на этапе компиляции, но все равно нужны runtime проверки.
В смысле? У теюя там будет просто массив с динамическим размером. Работай на интервалах итераторв -- будет тебе безопасно без проверок.
L>Возможно. А возможно это дает о себе знать культура, сложившаяся в сообществе С++ программистов
Ну там есть несколько нехороших парней, которые сами по себе может и хорошие инженеры, но пример показать любят дурной...
Вообще там слишком много, на мой вкус, перекоса в математику.
E>>1) Добавим методы типа operator[] такой и сякой. E>>2) Добавим методы/функции формирования/создания E>>3) Запретим неправильные пути создания и разрушения L>Мой метод, определить это все безобразие внутри срр файла и использовать только в нем. И ничего не придется ограничивать
Зачем? А если ты хочешь отдать дерево наружу? Так надо какой-то интерфейс тулить, а так просто отдаёшь наружу живую структуру, которой можно [53], например сказать или GetCountOfNodeElements() скажем...
Так легко может оказаться и удобнее и безопаснее и быстрее...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском