powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Вопросы начинающего - функции для работы со строковыми лексемами
23 сообщений из 73, страница 3 из 3
Вопросы начинающего - функции для работы со строковыми лексемами
    #38957341
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вахромкин. strchr внутри себя содержит еще один цикл. Подумай есть ли смысл троекратно
запускать его внутри твоих циклов?
...
Рейтинг: 0 / 0
Вопросы начинающего - функции для работы со строковыми лексемами
    #38957387
Andrey Vahromkin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
mayton,

Ну это не лучший вариант, конечно. Попробую вечерком переписать вообще без str...
Но у меня возникает вопрос - в Си вообще пользуются функциями из стандартных библитек? ;)
...
Рейтинг: 0 / 0
Вопросы начинающего - функции для работы со строковыми лексемами
    #38957392
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Выделение памяти операция тяжелая, поэтому там где можно обойтись без нее - лучше без нее. Поэтому второй вариант будет быстрее.
Во-вторых память экономить никогда не мешало.

В обоих вариантах накосячено с контролем выхода за пределы word, точнее во втором вообще нет контроля (в моем примере была проверка end), а в первом размер жестко задан STR_BUFFER, завтра захочешь поменять STR_BUFFER и он изменится для всей твоей проги. Размер буфера надо в параметрах передавать.

По поводу нескольких разделителей и strchr() для проверки - это нормально. Можно strspn() задействовать для поиска начала следующего слова.

Дальше вопрос по архитектуре: задача какая решается? получать одно-два слова из каждой строки или разобрать строку на слова? Если второе, то архитектура корявая, т.к. каждый раз начинаешь с первого слова. Поэтому эффективнее всего возвращать указатель на символ сразу за найденным словом и следующий проход начитать с этого места (у меня так было). Например надо получить 3,5,10-е слова, твой код прочитает 18 слов (3+5+10), мой 10.

Раз уж кодами ошибок пользуешься - задавай их дефайнами, так читабельнее
Код: plaintext
1.
2.
3.
4.
5.
6.
#define EW_OK   0
#define EW_NONE 1
...
if(...) return EW_NONE;
...
return EW_OK;
...
Рейтинг: 0 / 0
Вопросы начинающего - функции для работы со строковыми лексемами
    #38957393
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonstrchr внутри себя содержит еще один цикл. Подумай есть ли смысл троекратно запускать его внутри твоих циклов?
Это у него последовательно проверяется каждый символ на предмет является ли он разделителем. ИМХУ вроде ничего лишнего. Или у тебя есть идея как это сделать меньшим количеством операций?
...
Рейтинг: 0 / 0
Вопросы начинающего - функции для работы со строковыми лексемами
    #38957405
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Andrey Vahromkinу меня возникает вопрос - в Си вообще пользуются функциями из
стандартных библитек? ;)
Пользуются, конечно. Но поскольку программирование на языке С обычно ориентировано на
быстродействие результата, то стараются точно знать во что обойдётся их применение.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Вопросы начинающего - функции для работы со строковыми лексемами
    #38957460
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Andrey VahromkinПопробую вечерком переписать вообще без str...
Это лишнее. strchr() быстро работает. От того что ты ее "своими словами" перепишешь - код быстрее не станет. Также будешь перебирать массив разделителей.

Другое дело strdup() - динамическое выделение памяти и копирование всей строки. Это не быстро. Если надо будет повторить много раз - получишь тормоз.

В твоем последнем extractword() нет ничего лишнего. Разве что архитектуру пересмотреть (выше писал 17633636 )

Можно немного поуменьшать количество строк/букв кода, станет покрасивее, но не быстрее.
Например цикл for() вместо while() сделать
Код: plaintext
1.
2.
3.
for(int count = 0; count < n; count++) {
  ...
}
...
Рейтинг: 0 / 0
Вопросы начинающего - функции для работы со строковыми лексемами
    #38957475
Andrey Vahromkin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dima TВыделение памяти операция тяжелая, поэтому там где можно обойтись без нее - лучше без нее. Поэтому второй вариант будет быстрее. Во-вторых память экономить никогда не мешало.
Принимается, от этого и буду отталкиваться.
Dima TВ обоих вариантах накосячено с контролем выхода за пределы word, точнее во втором вообще нет контроля (в моем примере была проверка end), а в первом размер жестко задан STR_BUFFER, завтра захочешь поменять STR_BUFFER и он изменится для всей твоей проги. Размер буфера надо в параметрах передавать.
Проверку по end я действительно упустил из виду, а насчёт передачи размера буфера в параметрах я уже думал, но забыл написать, что вижу необходимость реализации этого :)
Dima TДальше вопрос по архитектуре: задача какая решается? получать одно-два слова из каждой строки или разобрать строку на слова?

Ну вообще на повестке дня - в дальней перспективе - замена нескольких perl-хелперов для прокси-сервера squid на более шустрые и компактные аналоги. На вход хелперы получают от 2 до 6 параметров. Полученные данные в хелперах участвуют в запросах к базе postgresql. В зависимости от результатов squid'у возвращают либо ОК либо ERR.
Сейчас начинаю упираться в скорость работы скриптов и потребление памяти. Попробовал переписать на freepascal как на знакомом с института, но был неприятно удивлен - perl-скрипты работают втрое быстрее паскалевского кода и памяти жрут меньше.

test.dat - 10000 строчек вида "Source_IP Destination_URL"
Засекал по 4 раза время отработки perl-скрипта и паскалевского исполняемого файла, ниже результаты
perl
time cat test.dat | ./bypass_auth.pl

4.053u 0.482s 0:42.00 10.7% 5+2838k 0+0io 0pf+0w
4.175u 0.579s 0:43.93 10.7% 4+2671k 0+0io 0pf+0w
4.270u 0.408s 0:42.95 10.8% 5+2767k 0+0io 0pf+0w
3.952u 0.518s 0:41.53 10.7% 5+2771k 0+0io 0pf+0w

pascal
time cat test.dat | ./sqBypass_Auth -u squid -p squid -b squid

15.327u 18.999s 2:03.62 27.7% 993+1768k 0+0io 0pf+0w
14.819u 20.901s 2:04.81 28.6% 1009+1797k 0+0io 0pf+0w
15.147u 21.269s 2:07.03 28.6% 1004+1788k 0+0io 0pf+0w
15.148u 21.762s 2:08.37 28.7% 984+1752k 0+0io 0pf+0w

Решил попробовать на Си реализовать. Первое с чем столкнулся - отсутствие split - соответственно, упёрся в способы разбора строк на составные части.
Далее предстоит искать какую-то замену перловому модулю URI для разбора url, получаемых от squid. Ну и способы доступа к postgresql.
Dima TЕсли второе, то архитектура корявая, т.к. каждый раз начинаешь с первого слова. Поэтому эффективнее всего возвращать указатель на символ сразу за найденным словом и следующий проход начитать с этого места (у меня так было). Например надо получить 3,5,10-е слова, твой код прочитает 18 слов (3+5+10), мой 10.
Учту, попробую это реализовать
Dima TРаз уж кодами ошибок пользуешься - задавай их дефайнами, так читабельнее

Да, спасибо, хорошая идея.

Dima TAndrey VahromkinПопробую вечерком переписать вообще без str...
Это лишнее. strchr() быстро работает. От того что ты ее "своими словами" перепишешь - код быстрее не станет. Также будешь перебирать массив разделителей.
Ну в общем да. Либо предварительно "причёсывать" строку дополнительной функцией, заменяющей разные разделители на какой-то один и удаляющей повторяющиеся лишние разделители
Dima TВ твоем последнем extractword() нет ничего лишнего. Разве что архитектуру пересмотреть (выше писал 17633636 )
Можно немного поуменьшать количество строк/букв кода, станет покрасивее, но не быстрее.
Например цикл for() вместо while() сделать
Код: plaintext
1.
2.
3.
for(int count = 0; count < n; count++) {
  ...
}


Спасибо, подумаю ещё сегодня вечерком :)
...
Рейтинг: 0 / 0
Вопросы начинающего - функции для работы со строковыми лексемами
    #38957538
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторSS1. Таким образом мы дойдём до комментариев
Код: plaintext
1.
int a;//переменная целого типа ...



А другой стороны - почему бы не сэкономить свое и чужое время, максимально подробно поясняя свои действия в ходе обучения?


Не надо заниматься ерундой. Если вас тут кто-то защищает, не думайте что вы тут правы во всём. Ваши комментарии неудачно расположены, и их слишком много даже для процесса обучения. Кто бы вас не защищал(от адекватных замечаний), это так.

авторКак я полагаю, исходя из вышепроцитированного, в рассматриваемом примере нет особой разницы - использовать malloc или calloc.
Первая будет быстрее, вторая позволит закрыть глаза на возможное отсутствие '\0' и мусора в размещаемой в памяти строки - закрывать глаза, наверное, не есть хорошо, но все же может оказаться полезным.По поводу "быстрее" - лично я сомневаюсь, что malloc тут даст какой-то существенный прирост в производительности, с другой стороны - возможно, в Си иные критерии существенности.
Было бы неплохо, если бы теперь вы пояснили, почему с вашей точки зрения calloc тут неоправдан, и что бы вы использовали вместо него.

если бы вы стандарт цитировали, тогда то что вы полагаете из "выше процитировано" имело бы место(это не какое-то "гнобление" или чего вы там напридумывали, а совет автору топика читать стандарт и ссылаться на него). И даже если то что вы процитировали верный перевод, то выделенное красным не соответствует действительности и неверно. функция calloc имеет побочный эффект(в контексте обычного аллоцирования ) при выделении памяти, и раз вы её используете, значит этот эффект вам нужен. Я бы подумал что это массив счётчиков, например.

авторextraction word - "извлечение слова"
word delimeters - "разделители слов"
get_word
delimeters or separators

вы сами справились. слова get set классика.
...
Рейтинг: 0 / 0
Вопросы начинающего - функции для работы со строковыми лексемами
    #38957560
egorych
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryавторextraction word - "извлечение слова"
word delimeters - "разделители слов"
get_word
delimeters or separators

вы сами справились. слова get set классика.ну, то есть претензий к n и str нет у нас, а вот к единственным, хоть как то полезно названным объектам программы - есть )))

А я бы, кстати, extractword оставил бы, оно больше подходит по смыслу к происходящему, чем get, а вот worddelim заменил бы на delimeters. word назвал бы, возможно, dst/destination, а str - src/source. Ну и n - такое прекрасное имя, но я бы его в m переименовал бы, обязательно ))))
...
Рейтинг: 0 / 0
Вопросы начинающего - функции для работы со строковыми лексемами
    #38957592
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Andrey VahromkinНу вообще на повестке дня - в дальней перспективе - замена нескольких perl-хелперов для прокси-сервера squid на более шустрые и компактные аналоги. На вход хелперы получают от 2 до 6 параметров. Полученные данные в хелперах участвуют в запросах к базе postgresql. В зависимости от результатов squid'у возвращают либо ОК либо ERR.
Сейчас начинаю упираться в скорость работы скриптов и потребление памяти. Попробовал переписать на freepascal как на знакомом с института, но был неприятно удивлен - perl-скрипты работают втрое быстрее паскалевского кода и памяти жрут меньше.

test.dat - 10000 строчек вида "Source_IP Destination_URL" ...
Полсекунды на разбор 10000 простых строчек это много для любого языка. Насколько я знаю разбор строк в перле достаточно быстро происходит.

Я бы для начала убедился в ту ли сторону копаешь. Сделай замеры времени:
1. тупо поставить return ОК и получить скорость вызова обработчика.
2. Оставить разбор, убрать запросы к БД и в конце return ОК
В итоге получишь из чего состоят эти полсекунды, т.е. время на вызовы обработчика, время разбора и время на обращения к БД.

Дальше смотри что получится: возможно надо изучать не Си, а как тюнинговать postgresql.
...
Рейтинг: 0 / 0
Вопросы начинающего - функции для работы со строковыми лексемами
    #38957932
Andrey Vahromkin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dima TПолсекунды на разбор 10000 простых строчек это много для любого языка. Насколько я знаю разбор строк в перле достаточно быстро происходит.
Я бы для начала убедился в ту ли сторону копаешь. Сделай замеры времени:
Это уже оффтоп, но что-то я тут возможности отправлять личные сообщения найти не могу - простите :(

Разбор строк, формирование запроса и собственно запрос к БД происходят практически мгновенно, у меня проблема в железе - на сервере памяти 2Гб, плюс там ещё зоопарк всякий живёт. А эти постоянные подключения/отключения и съедают львиную долю времени исполнения. Вот и думал попробовать ещё и на С, он все же побыстрее должен быть, ну и - заодно освоить новый язык хотя бы на уровне "пишу, заглядывая в справочник".
Тесты
1. Только split и OK

# time test.sh
0.075u 0.016s 0:00.09 88.8% 5+2986k 0+0io 0pf+0w
0.076u 0.015s 0:00.09 88.8% 6+3258k 0+0io 0pf+0w
0.076u 0.015s 0:00.09 88.8% 22+3004k 0+0io 0pf+0w

2. split, построение запроса и ОК без обращения к БД

# time test.sh
0.736u 0.086s 0:00.82 98.7% 5+2815k 0+0io 0pf+0w
0.773u 0.047s 0:00.81 100.0% 5+2788k 0+0io 0pf+0w
0.754u 0.063s 0:00.81 100.0% 5+2761k 0+0io 0pf+0w

3. split, построение и выполнение запроса с постоянным подключением к БД

# time test.sh
1.569u 0.118s 0:06.50 25.6% 5+2770k 0+0io 0pf+0w
1.584u 0.110s 0:06.52 25.9% 5+2955k 0+0io 0pf+0w
1.576u 0.120s 0:06.52 25.9% 5+3084k 0+0io 0pf+0w

4. split, построение и выполнение запроса с подключением к БД по запросу

# time test.sh
3.684u 0.554s 0:40.29 10.4% 5+2865k 0+0io 0pf+0w
3.731u 0.518s 0:40.39 10.4% 5+2807k 0+0io 0pf+0w
3.760u 0.473s 0:40.31 10.4% 5+2613k 0+0io 0pf+0w

# less test.sh
#!/bin/sh
cat test1.dat | ./bypass_auth.pl

test.sh (END)
...
Рейтинг: 0 / 0
Вопросы начинающего - функции для работы со строковыми лексемами
    #38957957
Andrey Vahromkin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Ойй, куда-то у меня строка из текста сообщения выпала, ерунда получилась...

Разбор строк, формирование запроса и собственно запрос к БД происходят практически мгновенно, у меня проблема в железе - на сервере памяти 2Гб, плюс там ещё зоопарк всякий живёт. Поэтому в скрипте подключение к БД происходит только после поступления строки на вход, а пока данных нет - скрипт к базе не подключен, и не занимает доступные соединения вхолостую. Вот эти постоянные подключения/отключения и съедают львиную долю времени исполнения. Вот и думал попробовать ещё и на С, он все же побыстрее должен быть, ну и - заодно освоить новый язык хотя бы на уровне "пишу, заглядывая в справочник".
...
Рейтинг: 0 / 0
Вопросы начинающего - функции для работы со строковыми лексемами
    #38957961
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Andrey VahromkinПоэтому в скрипте подключение к БД происходит только после
поступления строки на вход, а пока данных нет - скрипт к базе не подключен, и не занимает
доступные соединения вхолостую.
Connection pool? Не, не слышали о таком...
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Вопросы начинающего - функции для работы со строковыми лексемами
    #38957964
Andrey Vahromkin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dimitry SibiryakovConnection pool? Не, не слышали о таком...
Ну нельзя же знать всё на свете...
Вот услышал, читаю теперь, что это такое...
...
Рейтинг: 0 / 0
Вопросы начинающего - функции для работы со строковыми лексемами
    #38957985
wst
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я правильно понимаю, что в данном случае произвольный доступ к подстрокам не нужен? И формат разбираемых строк фиксированный?
...
Рейтинг: 0 / 0
Вопросы начинающего - функции для работы со строковыми лексемами
    #38958009
Andrey Vahromkin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
wstЯ правильно понимаю, что в данном случае произвольный доступ к подстрокам не нужен? И формат разбираемых строк фиксированный?
Не совсем понял вопрос.
Разные хелперы получают на вход строки различной конструкции.
Например

'ip url'
'login ip url'
'url ip/fqdn ident method'
'"username":"realmname"'

Иногда части строк могут отсутствовать
...
Рейтинг: 0 / 0
Вопросы начинающего - функции для работы со строковыми лексемами
    #38958016
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Andrey VahromkinDima TПолсекунды на разбор 10000 простых строчек это много для любого языка. Насколько я знаю разбор строк в перле достаточно быстро происходит.
Я бы для начала убедился в ту ли сторону копаешь. Сделай замеры времени:
Это уже оффтоп, но что-то я тут возможности отправлять личные сообщения найти не могу - простите :(

Тут демократичные модераторы, если оффтоп по существу - прощают :)

Andrey VahromkinРазбор строк, формирование запроса и собственно запрос к БД происходят практически мгновенно,
И чего ты тут хочешь улучшить? Магическое "написано на Си" не заставит процессор быстрее работать.

Твои замеры: 15 мс на вызов, 40-50 мс на разбор строк, 50-60 мс на выполнение запроса и 400 мс на установение связи с БД.

Теперь то что ты оптимизируешь: разбор 40-50 мс, допустим станет 0. выигрыш 10%. Но они не станут 0, уменьшатся максимум до 20-30 мс (если вообще уменьшатся), т.е. выиграешь 3-5%. Оно поможет?

На установке соединения с БД ты теряешь 80% !!! времени. Т.е. потенциал ускорить работу в 5 !!! раз. Просто допиши скрипт чтобы он поддерживал соединение и при необходимости умел восстанавливать.

Это решение твоей проблемы.

а это
Andrey Vahromkinу меня проблема в железе ... заодно освоить новый язык ...
твои домыслы и хотелки. Но если есть желание освоить - осваивай. Только чудес от использования Си не будет.
...
Рейтинг: 0 / 0
Вопросы начинающего - функции для работы со строковыми лексемами
    #38958021
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Andrey VahromkinВот эти постоянные подключения/отключения и съедают львиную долю времени исполнения.
Си тут ни при чем. Возможно там просто умышленно тормоз вставлен, чтобы подбор пароля усложнить. Держи соединение, оно ресурсы почти не тратит.
...
Рейтинг: 0 / 0
Вопросы начинающего - функции для работы со строковыми лексемами
    #38958030
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вахромкин. В большинстве задач оптимизации нужно смотреть в корень. А именно
в события ожидания. Готов спорить что у тебя это network events, ну на крайний случай
I/O. Переписывание pl скрипта на "C" ничего особенного не даст. Судя из твоих бенчмарков
между 1м и 2м тестом разница времени - 10х кратная. Это увеличение отклика появилось
после того как к split ты добавил подключение к БД.

Вот с него нужно и начать оптимизировать. Про pool уже сказали. Плюсик. Далее - где задержка.
Сетевые события? Посмотреть сеть? БД стоит локально? Подключить loopback, pipes. БД далеко?
Сократить маршрут. Есть возможность включить гигабит? Есть возможность снизить затраты на транспорт
информации? Снижай.

Далее. БД. После использования SQL-операций время снова удвоилось? Почему? Что за БД. Смотри
explain plan твоего запроса. Найди DBA ? Спроси у него чо как? Как ускорить? Может индекс построить
да там дофигища шаманста это я тебе как быв. DBA говорю. Море направлений.

Вот в таком вот аспекте.
...
Рейтинг: 0 / 0
Вопросы начинающего - функции для работы со строковыми лексемами
    #38958035
wst
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Смысл вопроса про фиксированный формат в том, что все эти extractword-ы можно заменить одним проходом strtok, при котором заполнялись бы соответствующие поля структуры с более гуманными названиями. Если данные резать за один проход, назначая им при этом нормальные идентификаторы, то:
Результат 1. вместо extractword9 (username, BUFFER_SIZE, ....); x(username); в коде будет что-то вроде x(s->username) - проще через полгода вспомнить про что вообще речь.
Результат 2. заполнение структуры отдельно от использования заполненной - меньше надо держать в голове при реализации что того что другого. Да и к новому формату входных данных если что проще приспособиться.
Дальше уже просто приятные мелочи:
Результат 3. меньше дерганий за выделение-освобождение памяти - меньше возможностей отстрелить ногу-другую.
Результат 4, мелкий бонус - есть все шансы что так еще и будет быстрее работать.
...
Рейтинг: 0 / 0
Вопросы начинающего - функции для работы со строковыми лексемами
    #38958164
Andrey Vahromkin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dima T, mayton
Да, похоже, мне нужно с вопросами переезжать в ветки с perl и postgresql :)
Что ж, сейчас пока разбираюсь, что такое pgbouncer/pgpool, и что лучше использовать...
Далее буду изучать, как с этим работает perl.
С тем не менее не брошу, всё-таки буду параллельно учиться на нем программировать.
wstСмысл вопроса про фиксированный формат в том, что все эти extractword-ы можно заменить одним проходом strtok, при котором заполнялись бы соответствующие поля структуры с более гуманными названиями.
Эх, а ведь и правда, и наверное, можно даже сразу разбирать строку по мере считывания ее из stdin... чудно, что это даже в голову раньше не приходило...

Господа! Огромное всем спасибо за помощь и участие!
Было приятно пообщаться и научиться (надеюсь) чему-то новому!
...
Рейтинг: 0 / 0
Вопросы начинающего - функции для работы со строковыми лексемами
    #38958194
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сообщи если надо перенести топик в профильный подфорум.
...
Рейтинг: 0 / 0
Вопросы начинающего - функции для работы со строковыми лексемами
    #38958225
Andrey Vahromkin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
maytonСообщи если надо перенести топик в профильный подфорум.
Да не надо, наверное, пока, во всяком случае.
У меня вопросы сейчас самые общие "что это такое и как оно работает". Сначала почитаю, попробую поставить, посмотреть, а там видно будет.
Еще раз спасибо!
...
Рейтинг: 0 / 0
23 сообщений из 73, страница 3 из 3
Форумы / C++ [игнор отключен] [закрыт для гостей] / Вопросы начинающего - функции для работы со строковыми лексемами
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]