Golang и XML

Json to XML, или «трансформировать за 6 секунд»

Привет, народ. Хочу поделиться с вами интересными подробностями работы нашего движка. Как вам известно, он написан на языке Go. В нем мы используем множество библиотек, и одна из них — mxj — великолепная библиотека для работы с xml.

Теперь я вкратце расскажу, как в нашем движке работает рутина json2xml. Первым делом мы преобразовываем json в map[string]interface{}, а затем кормим этот объект в mxj xmlValue, err := mxj.AnyXmlIndent(data, "", " ", "body"), потом мы чистим self-closed тэги и передаем объект дальше. Просто, не правда ли? Так мы работали 3 месяца, и все бы ничего, но внезапно нам потребовалось распарсить несколько бОльшие обьемы json-a чем обычно. И это оказалось проблемой. Один из диггеров работал 8 часов вместо 15 минут. На его базе мы и провели необходимые исследования. Обработка страницы занимала 16 минут, что, по понятным причинам, неприемлимо. Выяснилось, что там находится json в 2,5 Мб. Обработка в mxj занимала около 3 минут, а дальше случалась какая-то магия — движок сходил с ума и обрабатывал XML 13 минут. Естественно, нас это не устраивало, и мы решили ускорить для начала mxj.

Проблема библиотеки mxj заключалась в том, что при формировании xml автор использовал строковую конкатенацию. Всем известно что строки в Golang неизменяемые, соответственно каждая такая операция выделяет память под старую строку и новую строку, куда затем все это переносит. Мы решили обойти это и написали несколько функций, которые стали использовать bytes.Buffer вместо string, что ускорило mxj примерно в 180 раз, т.к. наш злосчастный json стал обрабатываться менее чем за 1 секунду.

Но это еще не все, как вы помните, движок сходил с ума, и обрабатывал результат около 13 минут. Настало время исправить и это. Изучив полученный xml, мы заметили теги которые наш html движок превращал в self-closed и рушил всю систему. Мы добавили несколько функций которые теперь позволяют на лету заменять теги на безопасные. Кстати эта функция скоро появится у нас в движке как команда что бы Вы сами могли менять поля на лету. Что же касается ускорения, то теперь страница, обработка которой занимала 15 минут, обрабатывается за 6 секунд.

Репозиторий с измененной нами библиотекой можно найти здесь.

Так же в качестве бонуса мы написали простой конвертер, который позволяет загружать данные из MongoDB и конвертировать их в XML, так же он работает с json файлами. Взять его можно тут.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *