Re[18]: Хозяйке на заметку: compile-time CRC32
От: Erop Россия  
Дата: 07.12.13 02:42
Оценка:
Здравствуйте, Lazin, Вы писали:

L>По поводу сишечки — я вот например иногда использую т.н. structure hack, для производительности, в c++ коде. Может ты сумеешь предложить типобезопасный аналог на шаблона, раз уж ты такой их фанат?



А в чём беда-то?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[33]: Хозяйке на заметку: compile-time CRC32
От: Lazin Россия http://evgeny-lazin.blogspot.com
Дата: 07.12.13 11:21
Оценка:
Здравствуйте, 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 не из условий задачи, в этом то и проблема
Re[34]: Хозяйке на заметку: compile-time CRC32
От: Erop Россия  
Дата: 07.12.13 20:13
Оценка:
Здравствуйте, 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 не из условий задачи, в этом то и проблема


Ну я про это и говорил, что если надо, можно дописать...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[17]: Хозяйке на заметку: compile-time CRC32
От: enji  
Дата: 08.12.13 05:12
Оценка:
Здравствуйте, SkyDance, Вы писали:

SD>
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, то "банально быстрее" убирает пару десятков мкс из пары десятков мс, что обычно ни о чем...
Re[18]: Хозяйке на заметку: compile-time CRC32
От: Sinclair Россия https://github.com/evilguest/
Дата: 09.12.13 18:15
Оценка:
Здравствуйте, Lazin, Вы писали:

L>APR умеет vectorised I/O, boost нет, apr может в базы данных(и даже умеет prepare), boost нет. По поводу сишечки — я вот например иногда использую т.н. structure hack, для производительности, в c++ коде. Может ты сумеешь предложить типобезопасный аналог на шаблона, раз уж ты такой их фанат?

Я давненько ничего не писал на плюсах, хочу уточнить: целочисленные параметры на шаблонах уже отменили?
template<n> struct Page {
public Page()
{
  this->num_items = n;
}
...
Metadata
...
int32_t num_items;
int32_t offsets[n];
};

Всё типобезопасненько. Ни один верификатор не подкопается.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[19]: Хозяйке на заметку: compile-time CRC32
От: Lazin Россия http://evgeny-lazin.blogspot.com
Дата: 10.12.13 08:23
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Я давненько ничего не писал на плюсах, хочу уточнить: целочисленные параметры на шаблонах уже отменили?

S>
S>template<n> struct Page {
S>public Page()
S>{
  this->>num_items = n;
S>}
S>...
S>Metadata
S>...
S>int32_t num_items;
S>int32_t offsets[n];
S>};
S>

S>Всё типобезопасненько. Ни один верификатор не подкопается.

Увы, n неизвестно на этапе компиляции, даже размер страницы неизвестен. Это пример из практики, там данные в страницу записываются с конца, а смещения этих данных добавляются в массив offsets. И так до тех пор, пока в странице есть место.
Re[35]: Хозяйке на заметку: compile-time CRC32
От: Lazin Россия http://evgeny-lazin.blogspot.com
Дата: 10.12.13 08:32
Оценка:
Здравствуйте, 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) Запретим неправильные пути создания и разрушения
Мой метод, определить это все безобразие внутри срр файла и использовать только в нем. И ничего не придется ограничивать
Re[20]: Хозяйке на заметку: compile-time CRC32
От: Sinclair Россия https://github.com/evilguest/
Дата: 10.12.13 08:52
Оценка:
Здравствуйте, Lazin, Вы писали:

L>Увы, n неизвестно на этапе компиляции, даже размер страницы неизвестен. Это пример из практики, там данные в страницу записываются с конца, а смещения этих данных добавляются в массив offsets. И так до тех пор, пока в странице есть место.

Ну, во-первых, тогда вы говорите о struct hack второго порядка.
Потому что классический struct hack — это фиксированный заголовок и "плавающий" хвост. И с ним в C++ всё в порядке.
Для того, чтобы получить типобезопасность, нужно понимать, что вы называете типобезопасностью.
От каких именно ошибок должен вас застраховать компилятор? От выхода за границы страницы? Невозможно — вы же до рантайма ничего не знаете о структуре страницы.
Вся разница между С и С++ в возможности обеспечить инкапсуляцию.
На С++ я опишу страницу совершенно обычным объектом, где сначала идут фиксированные поля заголовка, затем "гибкий" список смещений записей, а потом уже данные записей. А целостность я гарантирую при помощи методов типа
record* page::get_record(int i)
{
  return (record*)(this->raw_data + this->record_offsets[i]);
}

и
record* page::add_record(size_t recSize)
{
  size_t newOffset = this->record_offsets[(this->rec_count)++] - recSize;
  this->record_offsets[this->rec_count]=newOffset;
  return (record*)(this->raw_data + newOffset)
}
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[36]: Хозяйке на заметку: compile-time CRC32
От: Sinclair Россия https://github.com/evilguest/
Дата: 10.12.13 09:04
Оценка:
Здравствуйте, 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.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[36]: Хозяйке на заметку: compile-time CRC32
От: Erop Россия  
Дата: 10.12.13 10:11
Оценка:
Здравствуйте, Lazin, Вы писали:

L>Я не вижу способа сделать это действительно безопасным. Ну то есть можно кое что предпринять на этапе компиляции, но все равно нужны runtime проверки.


В смысле? У теюя там будет просто массив с динамическим размером. Работай на интервалах итераторв -- будет тебе безопасно без проверок.

L>Возможно. А возможно это дает о себе знать культура, сложившаяся в сообществе С++ программистов

Ну там есть несколько нехороших парней, которые сами по себе может и хорошие инженеры, но пример показать любят дурной...
Вообще там слишком много, на мой вкус, перекоса в математику.

E>>1) Добавим методы типа operator[] такой и сякой.

E>>2) Добавим методы/функции формирования/создания
E>>3) Запретим неправильные пути создания и разрушения
L>Мой метод, определить это все безобразие внутри срр файла и использовать только в нем. И ничего не придется ограничивать

Зачем? А если ты хочешь отдать дерево наружу? Так надо какой-то интерфейс тулить, а так просто отдаёшь наружу живую структуру, которой можно [53], например сказать или GetCountOfNodeElements() скажем...

Так легко может оказаться и удобнее и безопаснее и быстрее...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[22]: Хозяйке на заметку: compile-time CRC32
От: TarasB  
Дата: 12.12.13 13:22
Оценка: :)
Здравствуйте, Lazin, Вы писали:

L>Что-то вроде этого:


L>
L>struct Page {
L>...
L>Metadata
L>...
L>int32_t num_items;
L>int32_t offsets[];
L>};
L>


Безо всяких хаков и УБ:
type Page (LoOfs,HiOfs : integer) is new record 
   ...
   Metadata
   ...
   Offsets : Integer_Array (LoOfs, HiOfs);
end record;
Re[9]: Хозяйке на заметку: compile-time CRC32
От: dimgel Россия https://github.com/dimgel
Дата: 19.12.13 09:57
Оценка:
Здравствуйте, niXman, Вы писали:

X>а mono и openjdk — костыли.


В чём заключается костыльность openjdk?
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.