Как стать автором
Обновить

Комментарии 45

НЛО прилетело и опубликовало эту надпись здесь
Спасибо!
Со временем всё будет, сейчас я один и разорваться мне сложно, есть и основная работа которой нужно уделять много времени.
Очень нужное дело, мне как-то нужен был простой HTML-парсер — так лучше libxml2 (которая HTML понимает чуть-чуть) ничего не нашлось.
А многопоточность отключаемая? Под Виндой заработает?
Как же HTML5 парсер от Google?
Этот репозиторий создан через год или два после того, как я начал проект, где нужен парсер. Видимо, не было ещё тогда этого парсера.
Привет!

Там есть функции у которых в конце имени есть "_single" — это значит что будет фигачить без тредов.
Вообще, меня просили сделать опцию сборки для выключения тредов вообще, на моменте компиляции. Сделаю на этих выходных.

Про винду. Я всё писал так, чтобы под студией собиралось. Даже есть созданный проект. Но с того времени были добавлены всякие файлы которых в VS проект не включены. В общем, проще говоря, нужно немного манипуляций и будет работать. Сам код (и трэды) должны корректно собираться и работать под Windows. Так же, на этих выходных оформлю, это не займёт много времени.
Ни в коем случае не критикую, вы молодец. Работа действительно проделана огромная. По себе знаю, как тяжело даются всякие парсеры. У меня только вопрос, почему все таки си? Неужели вокруг c++ невозможно сделать обвязку для других языков? Спрашиваю, как полный дилетант в этих вопросах. Я к тому, что всякого рода парсеры значительно более эффективны, будучи написаны на c++, чем на голом си. Я тут недавно занимался разбором парсера svg формата (librsvg). Там голый си и весь код построен на ужасных костылях из glib, имитирующих работу с объектами. Кроме того (не знаю как у вас), обычно код на си изобилует выделением/освобождением памяти на каждый чих, что, очевидно, не лучшим образом сказывается на скорости работы.
Некоторые проблемы с совместимостью у с++ действительно есть. C тут более унивесрален. И часто чтобы прицепить что- то написанное на c++ делают адаптеры на c
По поводу эфективности. В этом c уж точно не хуже чем c++. Про иммитацию работы с объектами- в c++ объекты под капотом похоже работают. Выделение/освобождение памяти- тут уж как написать. Тут тоже все как в c++.
Не холивара ради. Я знаю, что на си можно писать достаточно эффективно. Вопрос тут только в том, насколько громоздко это получится. Классический пример — qsort. На си вызывается функция сравнения через указатель. На c++ на шаблонах функция сравнения встраивается в код быстрой сортировки и в итоге работает, иногда даже в разы, быстрее. Да, на си вы можете выполнять быструю сортировку также быстро, но для этого вам придется ее код копипастить всякий раз, когда вам потребуется сортировать новый тип данных. И так во всём. Вот пример из недавнего. В librsvg есть функция смешивания двух изображений с использованием разных функций смешивания (normal, multiply, darken, lighten и т.п.). Так вот на си это сделано так: сначала цикл по пикселям, затем цикл по компонентам пикселя и уже в самой глубине switch, выбирающий нужную функцию. На c++ тоже самое: сначала switch, затем вызов одной и той же шаблонной функции обхода пикселей и компонент, но в качестве аргумента — лямбда функция обработки одной компоненты. Итог — меньше кода + быстрее работает.
Про громоздкость- да. Про скорость- можно на с сделать все то- же. Только выглядеть будет хуже(иногда сильно хуже). Например вместо шаблонных функций- директивы препроцессора. fxr.watson.org/fxr/source/sys/queue.h
Советую вам завести задачи на рефакторинг в си, ничего не мешает сделать как в с++.
qsort тоже можно сделать быстрее, юзайте ключевое слово inline и не юзайте дефолт qsort.
Я вообще не пишу на си. Но приходится пользоваться си библиотеками. Всякий раз, когда заглядываю под капот очередной библиотеки, хочется всё там переписать. Вот недавно подключал библиотеку hunspell. Это проверка орфографии, используется очень много где (firefox, chrome, open office и т.д.). И казалось бы, написана на c++. Как бы не так. Практически полностью там си код, за исключением нескольких мест. Вот, например функция, возвращающая список строк:
int suggest(char*** slst, const char* word);
Что это? с++?

Для меня у си только одно преимущество: возможность подключать си библиотеку со всеми оптимизациями к debug сборке c++ проекта.
на си это сделано так: сначала цикл по пикселям, затем цикл по компонентам пикселя и уже в самой глубине switch, выбирающий нужную функцию. На c++ тоже самое: сначала switch, затем вызов одной и той же шаблонной функции обхода пикселей и компонент, но в качестве аргумента — лямбда функция обработки одной компоненты

Хрен редьки не слаще (с)
Привет!

Во-первых это красиво! :)

А если серьезно, Си мне нравиться. Вначале начинал писать на плюсах, ничего против плюсов не имею, но плюсы всегда меня уводили в сторону. В том плане, что если я делал что-то не так, грубо говоря «конструктор» не сходился, то плюсы всегда предлагали что-то чтобы решить проблему. В какой-то момент код стал состоять из костылей, точнее выглядело всё как костыли. Появлялась ЛЕНЬ, зачем переделывать затык (а порой переделывать приходилось много, сложно рассчитать архитектуру такого проекта с разбега) если можно использовать какую-то фишку плюсов. Да и говоря откровенно, — я не знаю плюсы на столько чтобы писать на них что-то серьёзное. Знаю в плюсах, как наверное и многие, какой-то срез которым могу пользоваться.

Где-то читал такой забавный аргумент — компилятор Си можно написать в одну рожу, а вот Спп нет. Не хочу развивать флейм про языки. Мне нравится Си.

Память не выделаю на каждый чих, там есть что-то вроде «псевдо-менеджера» памяти.
Отличная работа :-)

Будучи бэкэнд разработчиком меня всегда не устраивали существующие хтмл парсеры


«Существующие парсеры» были «бэкэнд разработчиком»? Может, все-таки «будучи бэкэнд разработчиком, вы были не удовлетворены парсерами», или «парсеры не устраивали вас как бэкэнд разработчика» ;-)
Чисто оценочно, ибо оч мало инфы по времени парсинга в инете, — За сколько примерно парсит 100Кb, уточню характеристики: к примеру: один глубоко вложенный тег(концовка за серединой, т.е далее 50 кб) и три четыре тега в линию на одном килобайте
Ну или чтобы не думать: 50 вложенных тегов в друг друга меж каждым три-четыре линейных тега, общая длина строки 100КБ (Для полного счастья, — еще бы потребный объём памяти для работы под эти 100КБ)
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
Мне предоставили 7ГБ порнушных html страничек (~62000 штук), минимальный размер 3 938 Б (таких не много), а максимальный 64 738 525 Б (таких тоже не много). Парсер обрабатывает их за ~100 сек. на 2,3 GHz Intel Core i7.

Я ставил себе задачу парсить 1000 за секунду. Рандомно брал 1000 страниц, среднее время парсинга составило 0.8 сек. Вообще, наверное, сейчас про скорости говорить не совсем корректно. Сейчас основная задача обеспечить нужный функционал и стабильность работы. Мест где можно разогнать там очень много. Старался писать код так чтобы в дальнейшем можно было «разогнать» его. По скоростям с другими не сравнивал, но мне тут сказали, что даже в однопоточном режиме он быстрее гугловского, возможно это правда.

В недалёком будущем, как все леса сниму, обязательно проведу тесты, построю графики и прочее. Сейчас это beta. Суть её в том чтобы получить фитбэк. Ведь возможно, что это никому не нужно и тогда что-то делать дальше не будет иметь смысла.
Была идея приделать услугу внешнего поисковика к произвольному сайту( т.е.: Аякс=>PHP=>C -обработчик ) с формированием пакета специфических наукообразных запросов(т.е. формировать базу специфических запросов по предмету), посколь тот же поисковик от гугла к сайту выдаёт нужную инфу лишь при десятке схожих запросов, имея базу можно бы сразу формировать пакет нужных-подобных, близких по значению. Поисковик-синонимайзер наукообразных фраз.
Я ставил себе задачу парсить 1000 за секунду. Рандомно брал 1000 страниц,, среднее время парсинга составило 0.8 сек
Приличные результаты. Когда пытался тестить существующие, заметил что наибольшее падение скорости на ошибках разметки в линейных, не вложенных тегах(либо слабовложенных) поскольку они чаще всего остаются на конец распарса
А зачем его призывать? Можно вроде самому проверить, у них же есть пробная версия.
Да, я даже скачал её, но это было дней 20 назад, наверное она уже всё, не успел. На данном этапе я активно ищу баги. Гоняю valgrind. Статические анализаторы следующие. + покрытие тестами. Работы много.
Вот вам небольшой отчёт от беглой пробежки cppcheck: fpaste.org/321329
Спасибо!
Буду разбираться.
На данном этапе я активно ищу баги.

source/myhtml/mystring.c
void myhtml_string_clean_all(myhtml_string_t* str)
{
    memset(str, 0, sizeof(myhtml_string_t));
}

В myhtml_string_t есть указатель data на выделенную память. Когда он затирается нулём, память остаётся выделенной и превращается в утечку.

myhtml_string_init()
char * myhtml_string_init(mchar_async_t *mchar, size_t node_idx, myhtml_string_t* str, size_t size)
{
    str->data     = mchar_async_malloc(mchar, node_idx, size);
    str->size     = size;
    str->node_idx = node_idx;
    str->mchar    = mchar;
    
    myhtml_string_clean(str);
    
    return str->data;
}


НЛО прилетело и опубликовало эту надпись здесь
Да, всё так. Это просто затералка.
НЛО прилетело и опубликовало эту надпись здесь
Аккуратность тут ни при чём. Ниоткуда не следует, что туда нельзя подавать структуру с выделенной памятью. Он просто это ПОМНИТ. Хорошо, когда у тебя только один проект и ты в нём только один разработчик. Но обычно разработчиков десятки (незнакомых друг с другом), а проекты похожи друг на друга, как капли воды.
Так что он заложил мину, на которую сам же и наступит.

Это дело либо должно быть хорошо и недвусмысленно названо, либо откомментировано, либо вообще находится в конструкторе этой структуры. Так же возникает вопрос: нахрена эта функция вообще нужна, если она — ни рыба, ни мясо?
Вы правы. Рефакторинг тоже будет, подобные «леса» будут изменены.
Возможно, стОило написать обёртку над HTML5-парсером Gumbo от Google, написанным на том же C.
Нет. Ничего не имею против гугла или его парсера, но нет. Я смотрел его, правда когда всё это задумывалось и реализовывалось про гугл парсер ничего не было слышно, его ещё не было. Мне не нравится как написан их парсер. Мы с ним в разных весовых категориях.

Gumbo is intentionally designed to turn an HTML document into a parse tree, and free that parse tree all at once.

Более того, первый мой парсер так и был написан. Так как не надо было заботиться о последующей работе с деревом, парсер работал крайне быстро, делал 1000 страниц за ~0.300 сек.
Мы с ним в разных весовых категориях.
В каком смысле, Александр?
Задачи у нас разные. Он (Gumbo) работает по третьему типу (описано в статье). «Парсим и Умираем» — эта особенность всех парсеров. Именно эта особенность не позволяет им развиться во что-то большее, у них есть потолок. Городить надстройки над этим — костыль. Парень из гугла молодец, он решил конкретную задачу — парсить HTML 5.
Так ведь разбор кода и дальнейшая работа DOM-деревом — вполне самостоятельные, независимые задачи. Можно написать свой механизм работы с DOM, но при этом освободить себя от такой низкоуровневой задачи, как разбор непосредственно кода, используя для разбора кода соответствующую специализированную библиотеку, делающую это с гарантированно высоким качеством и имеющую сильную поддержку со стороны сообщества.

В DOM со временем фундаментально меняется мало, а HTML находится в постоянном развитии, и на голом энтузиазме пары человек проект со временем рискует неизбежно устареть, что вряд ли случится с таким проектом, как Gumbo.
Про не устаревание у гугла я бы не говорил. Я вас услышал.
Как точно выглядит комментарий из 2018го.
Gubmo Latest commit aa91b27 on 29 Jun 2016
А как тестируете? Вижу пару тест-кейсов тут ( github.com/lexborisov/myhtml/tree/master/test/html ) — это все или еще что-то есть? Страшно как-то парсер почти без тестов использовать :) html5ever и gumbo, например, github.com/html5lib/html5lib-tests используют.
Все тестирование сводится к проверки что всё работает по спецификации, и поиску ошибок, пока вручную. Руки не доходят прогнать html5lib тесты, сделать не сложно, но вот руки пока не дошли. Будут обязательно в ближайшее время. Это крайне важная часть, чтобы дальнейшие изменения не ломали логику построения дерева. Если руководство разрешит то завтра же и сделаю. Спасибо, что напомнили.
Буду рассматривать ваш проект когда понадобиться что-то подобное :)
Спасибо за проект!
Вам спасибо!
Писать есть о чём, материала много, но вот времени всё не хватает. Написать качественно статью задача не на пару часов, к сожалению.
Зарегистрируйтесь на Хабре , чтобы оставить комментарий

Публикации

Истории