Fork me on GitHub
#clojure-russia
<
2016-02-19
>
rmuslimov05:02:34

Ребята, а кто тут по data.xml зипперам сможет подсказать? Почему clojure версия в >3x медленее python версии вот этого скрипта: clojure - https://gist.github.com/rmuslimov/9fccefd7b5528234ed07 python - https://gist.github.com/rmuslimov/5e4a7fbc2bd892b3f104 clojure ~ 1.06 sec, python - 0.37sec

rmuslimov05:02:47

причем если вынести zx/xml1-> до время кложи тает до 0.22 sec

artemyarulin06:02:35

@rmuslimov: Хм, странно. Т.е. почти секнду занимает именно поиск :body :tag?

artemyarulin06:02:35

а если переписать использую чисто zip/down, zip/next и циклом? Быстрее будет? Ну чтоб понять что проблема именно в xm1->

artemyarulin06:02:45

а большой xml?

rmuslimov06:02:14

сейчас перепишу да

rmuslimov06:02:08

там лежит >1K xml файлов разного размера

rmuslimov06:02:42

но вообще маленькие все

artemyarulin06:02:58

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

artemyarulin06:02:01

хз, теория

rmuslimov06:02:29

если сделать убержар то как будто кешируется и быстрее

rmuslimov06:02:40

java -jar ../target/uberjar/logprocessor-0.1.0-SNAPSHOT-standalone.jar "Elapsed time: 1029.173557 msecs" "Elapsed time: 624.421729 msecs" "Elapsed time: 598.651636 msecs" "Elapsed time: 600.90551 msecs" "Elapsed time: 631.414071 msecs" "Elapsed time: 519.10315 msecs"

artemyarulin06:02:02

ну все равно дофега

rmuslimov06:02:19

но вообще стыдно потому что этот xml1-> во всех туториалах по многу раз

rmuslimov06:02:24

в методах

artemyarulin06:02:52

там кода то на самом деле 20 строк, должно работать так же быстро

artemyarulin06:02:23

Ну попробуй да на чистых зипперах, без хелперов. Если так же медленно - то тогда проблема по крайней мере не в xml->

artemyarulin06:02:16

я использую зипперы счас много где, но до прода пока не дошло, поэтому не знаю про перформанс. Но когда в репле сижу то (я думал мне казалось) - иногда просиходили задержка на секунду может на простейших зиперах

artemyarulin06:02:59

или там хттп запросы были, чота не упомню уже

rmuslimov06:02:44

(defn get-xml-method-name2 [zipper] (-> zipper zip/down zip/right zip/down zip/down :tag))

rmuslimov06:02:51

такой же медленный

rmuslimov06:02:58

"Elapsed time: 1045.470172 msecs"

artemyarulin06:02:10

ага, гуд, проблема не в макросе

rmuslimov06:02:28

(defn get-xml-method-name3 [zipper] zipper)

rmuslimov06:02:36

а этот "Elapsed time: 242.988698 msecs"

artemyarulin06:02:57

а зиппер не ленивый случаем?

artemyarulin06:02:08

т.е. когда ты его не дергаешь, он и не делает ничо

rmuslimov06:02:49

хм а куда нужно посмотреть?

rmuslimov06:02:10

(defn get-zipper [filename] (-> filename io/file io/input-stream xml/parse zip/xml-zip))

artemyarulin06:02:36

по типу можно взглянуть наверно, сча исходник посмотрю

rmuslimov06:02:29

clojure.lang.PersisitentVector

artemyarulin07:02:55

хм, странно все это

artemyarulin07:02:26

в теории xpath будет работать быстрее зипперов, хотя не уверен на самом деле как она там работает, может через sax парсеры

artemyarulin07:02:43

может попрофайлеришь чтоб не гадать?

rmuslimov07:02:12

профайлерить это как нужно делать?

artemyarulin07:02:04

кто тут есть жмв опытом? какой профайлер можно поюзать?

artemyarulin07:02:51

а выложи пример хмл в тотже гист если можно

artemyarulin07:02:05

пока делать нечо с утра, поиграюсь

rmuslimov07:02:25

угу выложил

rmuslimov07:02:13

спасибо! Вы мне посоветуйте как профайл делать, я тоже завтра смогу с этим посидеть

artemyarulin07:02:12

вот тут друган посоветовал вот этот https://www.yourkit.com/

artemyarulin07:02:13

прикольно что я делаю один в один: парсю soap с помощью зипперов simple_smile Но у меня CLJS на react-native, там вариантов не так много. А у тебя @rmuslimov какие причины? Для жавы же есть всякие wsdl генераторы?

artemyarulin07:02:16

пажди, не понимаю - как ты решаешь проблему namespaces? <SOAP-ENV:Body> не будет находиться если юзаешь просто :Body же

artemyarulin07:02:22

опа, а не в этом ли причина? Зиппер не находит ноду и вынужден пройти весь хмл, неа?

rmuslimov07:02:37

да вроде находит

artemyarulin07:02:44

а неа, отмена. Ты же грил что (-> zipper zip/down zip/right zip/down zip/down :tag)) тормозит ведь тоже

rmuslimov07:02:38

да, точно также

rmuslimov07:02:49

я тут поменял count на set

rmuslimov07:02:52

{:EndTransactionRQ :OTA_CancelRQ :ContextChangeRS :AddRemarkRS :SessionCloseRQ :OTA_HotelResRS :AddRemarkRQ :HotelPropertyDescriptionRS :ContextChangeRQ …..

rmuslimov07:02:11

просто чтоб показать что данные у него есть и парсится верно

rmuslimov07:02:01

> А у тебя @rmuslimov какие причины? Да, больше для интереса - хотел спарсить логи на AWS S3 и положить в ES

artemyarulin07:02:17

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

rmuslimov07:02:16

еще одна интересная деталь

rmuslimov07:02:24

(defn get-xml-method-name2 [zipper] (-> zipper zip/down zip/right zip/down zip/down :tag))

rmuslimov07:02:31

вот если убрать тут zip/right

rmuslimov07:02:34

то получается

rmuslimov07:02:54

> (parse-all) "Elapsed time: 382.461758 msecs"

rmuslimov07:02:15

а без него > (parse-all) "Elapsed time: 1131.099081 msecs"

rmuslimov07:02:38

несколько раз перезапускал

prepor08:02:04

@rmuslimov: твои замеры скорости довольно мало о чем говорят. используй https://github.com/hugoduncan/criterium для бенчей

rmuslimov08:02:00

Evaluation count : 60 in 60 samples of 1 calls. Execution time mean : 1.157558 sec Execution time std-deviation : 51.014212 ms Execution time lower quantile : 1.086369 sec ( 2.5%) Execution time upper quantile : 1.249452 sec (97.5%) Overhead used : 9.041528 ns

artemyarulin08:02:11

да неа, когда разница в 10 раз то тут можно и так понять что проблема не в том как бенчится

artemyarulin08:02:41

хотя может prepor и прав - бенчить тоже надо уметь, я походу не умею:

(time (run! (fn[_](-> (zipper))) (range 1000)))
;; 314ms
(time (run! (fn[_](-> (zipper) zip/down zip/right)) (range 1000)))
;; 312ms

prepor08:02:21

> да неа, когда разница в 10 раз то тут можно и так понять что проблема не в том как бенчится то что разница будет — понятно. но что бы валидно сравнивать цифры, следить за прогрессом — нужно бенчить так. разница может быть в те же 10 раз после прогрева жита, в зависимости от кода

artemyarulin08:02:56

ну ага, @rmuslimov показывал что при убержаре вторые итерации уже на 40% быстрее

artemyarulin08:02:38

А кто знает как в итоге xpath работает? Там через SAX парсер? Я могу же дать 40ГБ хмл и xpath запрос и любая либа радостно вернет мне все результаты не сжирая 40гб оперативы

rmuslimov08:02:13

вот кажется эти ребята тоже что то подозревают

rmuslimov08:02:04

ну xpath это просто соглашение, может быть натянуто и поверх sax, и dom

artemyarulin08:02:15

т.е. получается парсинг самого xml тормозит?

artemyarulin08:02:11

странно что тогда просто (defn get-xml-method-name3 [zipper] zipper) в 4 раза быстрее

rmuslimov08:02:44

я не знаю, мне почему кажется что вот эти зиппер методы медленные

artemyarulin08:02:46

аа, или парсинг xml ленивый и каждый раз когда ты дергаешь zip/down, etc. ты в итоге дергаешь clojure.xml?

rmuslimov08:02:00

right left и т.п

niquola08:02:30

Я xml толстенький обернутым saxon парсил и расковыривал. В clojure поддержка XML игрушечная и на конвертацию слишком много ресурсов надо. Можно наверно zippers поверх saxon сделать.

rmuslimov08:02:30

[clojure.zip :as zip]

artemyarulin08:02:35

ну я строку к зипперу привожу как: (xml/parse (new org.xml.sax.InputSource (new java.io.StringReader xml-s)))

artemyarulin08:02:03

но он возвращает полносью распарсенный xml, т.е. тупо мапу

artemyarulin08:02:24

там зиппер не может тормозить в принципе - по мапе пробежаться ничо не стоит вообще

artemyarulin08:02:59

@rmuslimov: Попробуй отделить зипперы от создания xml в твоем бенче

artemyarulin08:02:48

ааа, я уже ничо не понимаю - создание зиппера из строки стокже занимает скок и пройтись по зипперу. Все, я не умею бенчить, сливаюсь simple_smile

rmuslimov08:02:39

да, перебросил создание зиппера - ничего не поменялось

rmuslimov08:02:05

спасибо за помощь - завтра продолжу ковыряться

artemyarulin08:02:18

можно вот это прочитать http://blog.korny.info/2014/03/08/xml-for-fun-and-profit.html, так чувак в конце как раз дамп вики на 42 гига парсит зипперами и ессно все ленивое, может в ленивости ответ

artemyarulin08:02:01

оо, точняк, ускорил в 3 раза

artemyarulin08:02:45

lazy-parsing часть в этой статье

artemyarulin08:02:00

а неа, у тебя уже используется оно

niquola10:02:36

А сделай на xpath для сравнения

artemyarulin14:02:12

я чойта наверно устал сегодня уже

>(macroexpand `(-> {:a 2} identity))
(clojure.core/identity {:a 2})
>(macroexpand `(-> {:a 2} (fn[a] a)))
IllegalArgumentException Parameter declaration {:a 2} should be a vector  clojure.core/fn (core.clj:4375)

artemyarulin14:02:39

все, пора домой, репл устал или чо?

fxposter14:02:27

(-> {:a 2} (fn[a] a)) ведет в (fn {:a 2} [a] a)

artemyarulin14:02:10

точно, еще пара скобок спасает

niquola14:02:24

Макрос есть макрос - нашел форму - вставил

artemyarulin14:02:33

ну да ага, а еще такой вопрос: Как такое ((fn[x] {:a 22}) 22) перевести в # синтаксис?

artemyarulin14:02:16

ближайшее что я смог это (#(identity {:a %}) 22)

artemyarulin14:02:34

покороче низя никак?

larhat14:02:59

constantly?

artemyarulin14:02:52

заместо identity? Дак на 2 длиннее даж

larhat14:02:31

а, я глянул только на ((fn[x] {:a 22}) 22)`

larhat14:02:41

где какбы x не участвовал :)

artemyarulin14:02:49

да, с параметром бы

artemyarulin14:02:06

тьфу, забыл задействовать)

niquola14:02:52

(#({:a %}) 22)

fxposter14:02:00

а зачем вообще?

artemyarulin14:02:01

ArityException Wrong number of args (0) passed to: PersistentArrayMap clojure.lang.AFn.throwArity (AFn.java:429)

fxposter14:02:35

можно просто (-> :a {:a 20})

fxposter14:02:50

или что тебе нужно?

artemyarulin14:02:38

да неа, мне не особо нужно - просто сделать анонимную функцию которая возвращает мапу можно использую либо fn синтаксис, либо с # но надо identity добавить

artemyarulin14:02:45

просто думал мож есть еще какие варианты

fxposter14:02:59

нет других вариантов simple_smile

artemyarulin14:02:46

грусть печаль, петля и гроб rage4

artemyarulin14:02:55

пойду пить simple_smile

niquola14:02:22

Мой вариант должен работать :)

larhat14:02:31

в tryclj не работает

artemyarulin14:02:34

дак вот я тока что в репле прогнал

fxposter14:02:47

user=> (#({:a %}) 22) ArityException Wrong number of args (0) passed to: PersistentArrayMap clojure.lang.AFn.throwArity (AFn.java:429)

niquola14:02:58

А сделай макроэкспанд

fxposter14:02:29

((fn* [p1__1279#] ({:a p1__1279#})) 22)

artemyarulin14:02:43

>(macroexpand `(#({:a %}) 22)) ((fn* [p1__4611__4612__auto__] ({:a p1__4611__4612__auto__})) 22)

fxposter14:02:45

проблема что он пытается ВЫЗВАТЬ хеш

fxposter14:02:49

без аргументов

niquola14:02:29

Ах сцука какая тогда (#(hash :a %) 22)

artemyarulin14:02:48

(#(hash-map :a %) 22)

artemyarulin14:02:55

работает ага

artemyarulin14:02:26

((fn[x] {:a x}) 22) (#(hash-map :a %) 22) еще длиннее чем с fn simple_smile

artemyarulin14:02:58

пойду пить все равно. Всех с пятницей simple_smile

larhat15:02:13

в рф сегодня ложная пятница

ul15:02:34

это как ложные опята?

a.espolov15:02:02

не после ложных опят не встают

niquola15:02:10

Завтра рабочий день

niquola15:02:27

Давайте hangout шедулить

fxposter15:02:27

а что у вас тут за хенгауты?

fxposter16:02:07

интересненько

niquola16:02:29

@michaelklishin Михаил, будешь гостем в clojure hangouts?