Информация об изменениях

Сообщение Re[5]: Тестовое задание: написать эффективный TCP-сервер от 12.02.2022 11:44

Изменено 12.02.2022 13:47 so5team

Re[5]: Тестовое задание: написать эффективный TCP-сервер
Здравствуйте, Тёмчик, Вы писали:

Тё>Я даже не удивлён, что ты этого не заметил, а только докопался до копирования.


Я отвечал на комментарий, в котором говорилось про копирование. И показал, что копирование там не только в том месте, на которое указал ArtDenis.

Тё>Общее впечатление, что писал человек без понимания алго-сложности, типично для C++ бекграунда.

Тё>https://github.com/w5346c/hash_server/blob/master/lib/request_responder_impl.cpp

Чтобы говорить про алго-сложность нужно знать точную постановку задачи. Я ее не знаю.

Судя по коду, автору нужно было разбить входной поток на отдельные строки и подсчитать хэш-код для каждой строки.
Если это так, то я бы сделал цикл разбора каждой прочитанной порции несколько иначе, используя find для '\n'. Что-то вроде (это набросок, который никак не проверялся и написан без оглядки на реальный API):
std::size_t current_pos = 0u;
while( auto nl_pos = request.find(current_pos, '\n'); nl_pos != std::string::npos ) {
  ... // Обработка очередного фрагмента строки.
  current_pos = nl_pos + 1u;
}
if( current_pos < request.size() ) {
  ... // Обработка остатка во входном буфере.
}


Но, по сути, это был бы тот же самый цикл от начала в конец входного буфера, как и у автора. Только с надеждой на то, что он будет несколько эффективнее, т.к. std::string::find может оптимизироваться до специфических инструкций CPU по обработке байтовых последовательностей. Хотя еще хрен знает во что современные оптимизирующие компиляторы развернут цикл, написанный в стиле:
for(std::size_t i = 0; i < len; ++i) {
  if(s[i] != '\n') continue;
  ...
}


Еще меня лично сильно смущает то, что автор накапливает "хвост" из входного буфера в отдельном std::string, который может расти неограниченно долго, в зависимости от входных данных. Следовало бы взять такую реализацию подсчета хэша, которой фрагменты строки можно было бы скармливать частями перед получением итогового результата. Но автор тестового задания явно такими вещами не заморачивался судя по коду.

Но, есть у меня впечатление, что ты, Тёмчик, будучи Ъ-экспертом по алгоритмам, разобъешь эти мои соображения в пух и прах. Так что с большим интересом, любопытством и смирением готов выслушать объективную критику и конструктивные соображения с твоей стороны.
Re[5]: Тестовое задание: написать эффективный TCP-сервер
Здравствуйте, Тёмчик, Вы писали:

Тё>Я даже не удивлён, что ты этого не заметил, а только докопался до копирования.


Я отвечал на комментарий, в котором говорилось про копирование. И показал, что копирование там не только в том месте, на которое указал ArtDenis.

Тё>Общее впечатление, что писал человек без понимания алго-сложности, типично для C++ бекграунда.

Тё>https://github.com/w5346c/hash_server/blob/master/lib/request_responder_impl.cpp

Чтобы говорить про алго-сложность нужно знать точную постановку задачи. Я ее не знаю.

Судя по коду, автору нужно было разбить входной поток на отдельные строки и подсчитать хэш-код для каждой строки.
Если это так, то я бы сделал цикл разбора каждой прочитанной порции несколько иначе, используя find для '\n'. Что-то вроде (это набросок, который никак не проверялся и написан без оглядки на реальный API):
std::size_t current_pos = 0u;
while( auto nl_pos = request.find(current_pos, '\n'); nl_pos != std::string::npos ) {
  ... // Обработка очередного фрагмента строки.
  current_pos = nl_pos + 1u;
}
if( current_pos < request.size() ) {
  ... // Обработка остатка во входном буфере.
}


Но, по сути, это был бы тот же самый цикл от начала в конец входного буфера, как и у автора. Только с надеждой на то, что он будет несколько эффективнее, т.к. std::string::find может оптимизироваться до специфических инструкций CPU по обработке байтовых последовательностей. Хотя еще хрен знает во что современные оптимизирующие компиляторы развернут цикл, написанный в стиле:
for(std::size_t i = 0; i < len; ++i) {
  if(s[i] != '\n') continue;
  ...
}


Еще меня лично сильно смущает то, что автор накапливает "хвост" из входного буфера в отдельном std::string, который может расти неограниченно долго, в зависимости от входных данных. Следовало бы взять такую реализацию подсчета хэша, которой фрагменты строки можно было бы скармливать частями перед получением итогового результата. Но автор тестового задания явно такими вещами не заморачивался судя по коду.



UPD. Если нужно только хэши для строк считать и все, то достаточно всего одного прохода по входному буферу из начала в конец с посимвольным скармливанием очередного символа вычислителю хэша (если очередной символ не '\n') и специальной обработкой символов '\n'. Тут даже не нужно отдельных подстрок выделять в каком-либо виде.



Но, есть у меня впечатление, что ты, Тёмчик, будучи Ъ-экспертом по алгоритмам, разобъешь эти мои соображения в пух и прах. Так что с большим интересом, любопытством и смирением готов выслушать объективную критику и конструктивные соображения с твоей стороны.