Привет, народ. Хочу поделиться с вами интересными подробностями работы нашего движка. Как вам известно, он написан на языке 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
файлами.