Fork me on GitHub
#clojure-russia
<
2017-02-07
>
kgofhedgehogs00:02:07

r/reduce conj {}

kgofhedgehogs00:02:53

На глаз стало быстрее, но все равно недостаточно

kgofhedgehogs00:02:24

Да. Прирост однозначно есть, но незначительный

kgofhedgehogs01:02:44

Нормальная же программа должна обрабатывать такое поле в риалтайм? А то у меня в среднем 3-4 кадра в секунду

kgofhedgehogs01:02:13

Попробовал pmap, почему-то лучше не стало

kgofhedgehogs01:02:21

Сейчас подумал, что это могут быть проблемы отрисовки

misha01:02:23

каких-нибудь тайп хинтов расставь может возле интежеров в координатах

misha01:02:46

еще можно (но не уверен) 1 трансдюсер сделать в game-step из r/map и r/filter, чтобы промежуточная коллекция не создавалась

kgofhedgehogs02:02:01

Сравнил разные варианты, самый быстрый это с reducers

kgofhedgehogs02:02:24

Затем пмап, а за ним фор, в конце с мапами вместо форов

kishanov02:02:28

https://www.youtube.com/watch?v=iQwQXVM6oiY - в этой презентации кладезь информации на тему “где подкрутить, чтобы быстрее работало"

kgofhedgehogs02:02:11

Спасибо. Ее я уже посмотрю завтра, наверное. Пятый час идет. Надо вздремнуть

kishanov02:02:25

(подразумевая, что алгоритм уже не улучшить 🙂 )

kgofhedgehogs02:02:52

Да я даже не знаю что мне тут улучшать. Менять главную структуру данных разве что

kgofhedgehogs02:02:18

А. r/map не поддерживает такой функционал. Он требует ровно два аргумента

kgofhedgehogs02:02:19

Расставил типы и применил трансдьюсер с обычным мапом. Ускорение есть, но все еще маленькое, но таким образом трансдьюсер + обычные мапы и фильтры стал быстрее r/ версий

kgofhedgehogs02:02:19

Непонятно почему, но разница от 0 сек до 5 в пользу трансдьюсера

kgofhedgehogs02:02:36

И я выиграл в среднем 1 секунду за ночь

artemyarulin05:02:34

а кста как профайлить код с кложурой? мож есть уже чего готовое?

delaguardo05:02:10

https://www.yourkit.com/java/profiler/ https://github.com/thunknyc/profile дофига всего есть, на любой вкус и цвет

mike_ananev07:02:58

да, tufte удобная вещь, если надо быстро и просто

mike_ananev07:02:13

интересное интервью со Степановым http://www.stlport.org/resources/StepanovUSA.html

mike_ananev07:02:25

тем самым, который сделал STL для С++

mike_ananev07:02:10

В частности интересно он отзывается об ООП

mike_ananev07:02:11

I find OOP technically unsound. It attempts to decompose the world in terms of interfaces that vary on a single type. To deal with the real problems you need multisorted algebras - families of interfaces that span multiple types. I find OOP philosophically unsound. It claims that everything is an object. Even if it is true it is not very interesting - saying that everything is an object is saying nothing at all. I find OOP methodologically wrong. It starts with classes. It is as if mathematicians would start with axioms. You do not start with axioms - you start with proofs. Only when you have found a bunch of related proofs, can you come up with axioms. You end with axioms. The same thing is true in programming: you have to start with interesting algorithms. Only when you understand them well, can you come up with an interface that will let them work.

mike_ananev07:02:33

I spent several months programming in Java. Contrary to its authors prediction, it did not grow on me. I did not find any new insights - for the first time in my life programming in a new language did not bring me new insights.

mike_ananev07:02:59

The best way to judge a language is to look at the code written by its proponents. "Radix enim omnium malorum est cupiditas" - and Java is clearly an example of a money oriented programming (MOP). As the chief proponent of Java at SGI told me: "Alex, you have to go where the money is." But I do not particularly want to go where the money is - it usually does not smell nice there.

mike_ananev07:02:48

Короче дядька уже тогда про трансдьюсеры говорил и про то что Рич говорит в части абстракций, функций

artemyarulin07:02:31

>money oriented programming надо запомнить

artemyarulin07:02:08

а С++ это разве не ООП?

mike_ananev07:02:14

Ну, строго говоря ООП это парадигма, а С++ язык с сильным упором на ООП, но на нем можно и в других стилях писать

mike_ananev07:02:32

Степанов как раз STL написал не в ООП стиле

mike_ananev07:02:49

он в интервью как раз и пишет почему ему ООП не нравится совсем

mike_ananev07:02:00

вообще в интервью много интересных мыслей

kgofhedgehogs09:02:50

Я раньше не профайлил программы, правильно понимаю, что я с помощью этого смогу увидеть, где у меня просаживается производительность?

prepor10:02:50

@kgofhedgehogs у тебя же в самой программе нет io, только вычисления

prepor10:02:53

а проц не загружен

prepor10:02:04

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

prepor10:02:26

что будет, например, если ты запустишь вычисления без вывода на экран?

prepor10:02:34

в лупе просто

prepor10:02:41

забьет проц?

prepor10:02:48

для профайлинга есть yourkit, но он денег стоит. но базовый профайлинг умеет и visualvm / jmc

kgofhedgehogs10:02:02

Я время замерял без вывода на экран. Проц не забивает. Это 100% не проблема отрисовки

artemyarulin10:02:05

оно одно ядро тока забивает может?

nwalkr10:02:26

гугли parallel image convolution, наверное

nwalkr10:02:05

суть та же самая.

nwalkr10:02:15

вообще, я бы попробовал тупо поделить общую плоскость на куски и новое их состояние вычислять параллельно.

dottedmag10:02:53

Эээ, а как-то по-другому можно? Если не делить, то накладные расходы ужасны.

nwalkr10:02:43

я даже не знаю, как по-другому. может быть тут есть кто-то умный, кто знает.

kgofhedgehogs10:02:17

Я как раз читал сейчас о chunked pmap

kgofhedgehogs10:02:26

Типа пмап мапов

prepor10:02:10

та при чем тут пмапы

prepor10:02:19

ты же одно ядро забить не можешь, так?

prepor11:02:09

или нет? что значит "cpu 17%"?

artemyarulin11:02:24

может это общая загрузка всей системы? Т.е. одно ядро из 4

andmed11:02:21

ага. встречал разные показатели. кто-то при полной нагрузке всех ядер показывает 100% кто-то k*100%

andmed11:02:28

системы не уловил. смотреть надо

prepor11:02:21

смысл в тех чатики то такое бросать

prepor11:02:35

не домохозяйки же!

andmed11:02:24

ну чел спрашивает

kgofhedgehogs11:02:44

Просто я домохозяйка :)

kgofhedgehogs11:02:21

Как освобожусь, скину детальную инфу

prepor11:02:25

> ну чел спрашивает та я ж не виню никого ^_^, разбираемся вот )

kgofhedgehogs11:02:14

Ну. Это значит, что ядро забивает полностью. Как мне сделать так, чтобы забивало несколько ядер?

prepor11:02:08

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

prepor11:02:15

для этого нужно профилировать

prepor11:02:20

смотреть что жрет

prepor11:02:40

yourkit 15 дней триала имеет )

kgofhedgehogs11:02:08

Устанавливаю

prepor12:02:33

Ну не нам знать! но скорее всего 64 бита )

kgofhedgehogs12:02:25

Так. Профайлер профайлит

kgofhedgehogs12:02:45

Дать ему попрофайлить, затем закрыть программу и смотреть отчет, так?

artemyarulin12:02:02

угу, а потом можно начать думать как парралелить кусок который больше всего занимает

prepor12:02:16

для начала их можно оптимизнуть!

prepor12:02:22

возможно

prepor12:02:25

а может нет

artemyarulin12:02:44

ну парралелизация вполне так себе оптимизация 🙂

kgofhedgehogs12:02:58

времени работы программы*

prepor12:02:13

к вопросу о распаралеливании и оптимизациям вслепую

kgofhedgehogs12:02:46

Блин. А как его с оптимизировать-то. Надо уменьшать подаваемую коллекцию..

prepor12:02:07

ну можно подумать нужна ли тебе тут такая группировка на каждом тике например или нет

kgofhedgehogs12:02:08

Нужна =( Это ключевой момент расчета следующего шага

prepor12:02:22

подумай!

kgofhedgehogs12:02:23

Нужно ее менять на другую

prepor12:02:28

может кешить можно вычисление

prepor12:02:33

и итеративно к нему приходить

kgofhedgehogs12:02:06

Ну вот клетки есть. У них есть соседи. Функция, на которой всё проседает, это подсчет кол-ва соседей. Узнать как изменится кол-во соседей не просчитав то же самое для клеток вокруг, нельзя. А если просчитать, то получится то, что я и сделал Пойду почитаю об оптимизациях этой игры. Может знающие люди придумали по-лучше моего

prepor12:02:45

ну как это нельзя

prepor12:02:01

у тебя есть AxB поле

prepor12:02:22

и два массива

prepor12:02:37

каждый AxB размером

prepor12:02:05

в одном содержится жива клетка или нет, а в другом сколько у нее соседей

prepor12:02:33

проходишь по первому в один проход и формируешь второй

prepor12:02:42

проходишь по второму и обновляешь первый

prepor12:02:55

никаких группировок, никаких аллокаций

kgofhedgehogs12:02:13

Дело в том, что я не храню мертвые клетки Я храню только живые клетки, т.к. их как правило меньшинство

prepor12:02:33

ты хочешь быстро или как ты сейчас? )

kgofhedgehogs12:02:39

Я хочу быстро..

prepor12:02:42

тебя не устраивает перформанс, ты хочешь быстрее

prepor12:02:54

значит тебе нужно подумать как можно сделать не так как ты сделал сейчас, а по другому

prepor12:02:22

вот тут парень линки дает

andmed12:02:25

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

prepor12:02:32

но там хтрожопенькие штуки предлагают

prepor12:02:30

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

prepor12:02:58

> тут есть повод подумать о кложе-с интеропе не нужно никакого кложаси интеропа тут, нужно просто написать нормально, в кложе достаточно всего для этого

prepor12:02:08

если не уходить в битоебство совсем

kgofhedgehogs12:02:12

Хорошо. Тогда надо мне пересмотреть структуру хранения данных: массив AxB, в котором содержатся цвета клеток, либо false. Нормально?

kgofhedgehogs12:02:42

Цвет клетки это [0xRr 0xGg 0xBb]

kgofhedgehogs12:02:06

Хотя, должен быть способ смешивать цвета храня их интами. Будет лучше, если в массиве будут числа, а не вектора

prepor12:02:24

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

kgofhedgehogs12:02:53

Хорошо. Спасибо большое

prepor12:02:07

1. я бы не стал как то оптимизировать особо структуру одной клетки в начале. {:red 155 :green 155 :blue 155} and :died должно быть достаточно. будет тормозить — оптимизнешь 2. а вот на массивы вместо векторов стоит перейти сразу. иммутабельные структуры не дешевы в модицифкации

prepor12:02:04

3. профайлер — твой помощник!

kgofhedgehogs12:02:51

Хорошо. Не буду преждевременно оптимизировать лишнее

az15:02:52

воу воу, сегодня я узнал новое слово “битоёбство"

az15:02:46

у меня вопрос, как часто “битоёбство” происходит на фронтенде

az15:02:01

то есть clj -> js нормально работает?

andmed15:02:11

кмк это к железу. маски, сдвиги, big endian и тд..

az15:02:30

ну если про железо, то это только про С, я вообще про борьбу с производительностью

az15:02:05

всё это жанглирование атомами в жс нормально укладывается?

andmed15:02:26

не знаю. вообще будет интересно посмотреть какой на кложе с массивами будет код

andmed15:02:40

речь о массивах шла

seryh15:02:46

а как можно использовать массивы избегая интеропа в java?

andmed15:02:53

это к препу))

andmed15:02:08

вообще там есть обертки кажется вроде make-array

seryh15:02:11

transient кстате не поможет?

seryh15:02:18

вроде на этот случай и есть

artemyarulin15:02:59

>то есть clj -> js нормально работает? на мобайле юзая CLJS + реакт нейтив иногда можно обжечься когда гоняешь CLJS <> js часто, во всяких листах при скроле и прочем

seryh16:02:55

если кложу на ноде гонять. тоже похоже просадки будут при CLJS <> js

alexander_mihailov16:02:19

Там даже без интеропа должно быть не очень круто. Код который генерится Clojure Compiler`ом на advanced optimisation ломает оптимизации в V8.

artemyarulin16:02:36

И это сильно влияет? Т.е. на сколько проседает в итоге, на 1%, на 10%, на 100% ?

rmuslimov16:02:37

а это общепризнанный факт? весьма серьезное заявление в свете следующего релиза closure-compiler который научиться читать imports. И с того момента можно будет переезжать с webpack на figwheel

rmuslimov16:02:52

Эта тема активно сейчас обсуждается в cljs-dev

artemyarulin16:02:47

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

artemyarulin17:02:00

хотя я такое тоже первый раз слышу

misha18:02:29

а кто что ищет/ожидает увидеть в результатах опроса?

artemyarulin18:02:06

The most interesting story here is the rise in three areas:

React Native - 18% (new choice this year)
Electron - 11% (new choice this year)
AWS Lambda - 9% (vs 5% last year)
не ожидал и приятно удивлен что RN так популярен. Ну и что CLJS догнало почти CLJ

kishanov18:02:25

да они там в когнитекте сами офигевают от того, где и как clojurescript используется. Они в него даже не инвестируют нормально (Нолен сидит датомик пилит), а он растет, как сорняк

misha18:02:40

вчера даже инстаграмм про RN написал

artemyarulin19:02:32

даже? это же фб 🙂

misha19:02:33

про RN вообще не удивительно - это ж покрытие целых двух новых платформ. кложа - бэкэнд, скрипт - фронтэнд, и теперь мобилы

misha19:02:29

ну типа да, fb, но всё равно от fb очень мало RN хайпа просачивается мне в эфир

misha19:02:01

про Вазу

kgofhedgehogs20:02:46

Я все еще с оптимизациями. Нет ли очевидных путей ускорить вот этот код?

artemyarulin20:02:14

это копипаста из clojure.core?

kgofhedgehogs20:02:25

Нет, мой код

artemyarulin20:02:27

ой сори не

kgofhedgehogs20:02:42

Это исправленный под мои нужды group-by, так что ты от части прав

artemyarulin20:02:02

а ок, а то я смотрю persistent transient

artemyarulin20:02:56

дак если под одно ярдо оптимизировать не выходит то чо насчет других простаивающих ядер? парралелить не хочешь?

kgofhedgehogs20:02:01

Просто это group-by был самым нагруженным местом в моей программе, теперь вместо него нагружен group-by-first-up-to-n

artemyarulin20:02:44

ну т.е. выигрыш то есть в итоге или просто название функции теперь другое?

kgofhedgehogs20:02:51

Мне тут верно сказали, что дерьмовый алгоритм лучше не параллелить, а переписать. Поэтому перед тем как его переписать и параллелить, я еще пытаюсь спасти его

kgofhedgehogs20:02:15

Выигрыш 3 секунды. Всего программа работает до 7 секунд

artemyarulin20:02:19

тебе тут много чего могут сказать - 420 человек в чатике 🙂

kgofhedgehogs20:02:30

Но мнение я поддерживаю

artemyarulin20:02:57

а ну ок, тогда копай дальше

kgofhedgehogs20:02:00

Параллелить это же с помощью go блоков и chan?

kgofhedgehogs20:02:07

Просто я думал, что есть какой-нить мультипроцессорный мап, который сам всё за меня сделает

artemyarulin20:02:13

эм, ну можно конечно и так. Т.е. если для фана то можно core.async еще притащить и разобраться с ним, но это может занять время

kgofhedgehogs20:02:29

Мне как проще, легче и читабельнее бы

artemyarulin20:02:15

на если уж легче и проще то я б сначала подкачал матчасть - как люди решают эту задачу, как ее паралелят, какие есть алгоритмы

rmuslimov20:02:36

core.async может усложнить проект, я помнится на первых порах больше мучался с ним

artemyarulin20:02:51

опять же это если цель проще - если для фана то лучше самому подумать 🙂

artemyarulin20:02:12

я вкурил core.async наверно через месяц тока ага(

kgofhedgehogs20:02:16

Матчасть справляется быстрее моего алгоритма и без параллеления

rmuslimov21:02:18

может быть взять claypoole, он простой понятный, позволяет рулить pool-executors

misha21:02:03

а что значит "работает до 7 секунд"?

misha21:02:29

какой размер поля у тебя? какой начальный сид?

misha21:02:40

со своей сравню opieop

misha21:02:53

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

kgofhedgehogs21:02:22

700х700 плотно расставленные рандомные три цвета клеток, есть пробелы. Рассчет следубщего поколения сейчас в среднем 5 секунд

artemyarulin21:02:07

это один проход всего поля 5 секунд?

misha21:02:20

а, ты еще цвета смешиваешь

kgofhedgehogs21:02:27

цвета это самая меньшая проблема

misha21:02:30

а сколько рандомных клеток сначала? есть координаты?

kgofhedgehogs21:02:00

(let [world (random-rgb-cells [0 700] [0 700])]
  (time
    (game-step
      world
      blend-colors
      {:birth      [3]
       :keep-alive [2 3]}
      [-25 725]
      [-25 725])))
=> "Elapsed time: 5431.698635 msecs"

kgofhedgehogs21:02:28

Закинуть координаты клеток?

misha21:02:29

так тут же в размере сида - самый сок

misha21:02:37

давай в личечку

misha21:02:51

и или покажи сорс random-rgb-cells

leov22:02:04

привет

leov22:02:10

а можно нубский вопрос по реакту?

leov22:02:33

у меня есть компонент "одометр", который показывает число и меняется как цифры в казино

leov22:02:38

я хочу его реактифицировать

leov22:02:25

как это сделано? в методе рендер пустой див. в didMount стоит включение этого стороннего компонента. в didUpdate стоит вызов изменений

leov22:02:28

чтобы он крутился

leov22:02:51

и всё вроде работает. 1) я не понимаю, почему, когда я в исходный див сделал непустым, положив туда число с текущим значением одометра, он не сбрасывает каждый раз по вызову метода рендер внутреннее состояние компонента.

leov22:02:36

componentDidMount: function(){
     this.odometer = new Odometer({
      el: this.getDOMNode(),
      value: this.props.value
    });
  },
  componentDidUpdate: function() {
   this.odometer.update(this.props.value)
  },
  render: function() {
    return React.DOM.div()
  }

leov22:02:20

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

leov22:02:13

2) я пошёл дальше, и зачем-то повторил в методе рендер всю внутреннюю разметку этого стороннего не-реакт плагина. в этот момент только начинаются жалобы от реакта "cannot find element with id=77", из чего я заключаю, что реакт наконец возмущён тем, что его разметку компонента кто-то грохнул, и он не может произвести правильно дифф.