Fork me on GitHub
#clojure-norway
<
2023-12-29
>
slipset07:12:04

Morn! En dag ute på vannet, og vi har plutselig en shadow-dom i cljs?

slipset07:12:26

Forøvrig. Jeg finner litt morro i benchmarkinga som viser at (hvis jeg leser det riktig) dumdom er søppletreig sammenlignet med React, men likevel er rask nok.

cjohansen07:12:00

Dumdom er veldig mye treigere ja! Har aldri tuna performance på den, men heller ikke opplevd store problemer :man-shrugging:

slipset07:12:38

Jupp, det er akkurat det som er interessant.

slipset07:12:48

Det er altså ikke en kritikk av dumdom som kode, men heller av oss som utviklere, “Det må være superraskt” og så viser det seg at “søppletreigt” er raskt nok.

👍 1
slipset07:12:40

På jobben gjøres det iblant en del rare ting i navnet til “bedre ytelse”.

slipset07:12:59

Uten at noen har gjort noe som helst for å forstå hvorfor vi har dårlig ytelse.

👍 1
cjohansen07:12:04

Jeg er generelt enig i dette, men synes samtidig at et sånt bibliotek bør starte fra et så godt sted som mulig, så man ihvertfall har mulighet til å bygge raske ting på toppen.

👍 1
slipset07:12:20

Man kan lett tenke seg at kode som dette eksisterer:

(swap! state assoc :a 1)
(swap! state assoc :b 2)
(swap! state assoc :c 3)
Noe som medfører tre renders, i steden for
(swap! state assoc :a 1 :b 2 :c 3)

cjohansen07:12:31

Tror du trygt kan kritisere dumdom-koden 😅

slipset07:12:48

Er helt enig i at det er lurt (som biblioteksforfatter) å ikke bygge tregt hvis man kan bygge raskt. Problemet er at folk roper etter raskt og forkaster nest-raskest når de egentlig bare trenger søppletreigt.

💯 2
slipset07:12:04

Og så blir det problematisk hvis raskest medfører komplisert kode utenfor biblioteket.

cjohansen07:12:14

Uten å helt ha tallene i hodet så er vel vdom-implementasjonen min nå ca like mye kode som dumdom, og i tillegg har dumdom flere forsøk på optimaliseringer med atomer og greier 😅

cjohansen07:12:35

Denne Implementasjonen har bare ett atom som brukes til å spare på hooks som skal kalles

slipset07:12:53

Har du profilert koden noe?

cjohansen07:12:58

Den opprinnelige løsningen var helt funksjonell og hadde ingen atomer, men ble skrevet om for ytelse. Det som er irriterende er at problemet jeg ville løse viste seg å være et annet sted, så jeg vet ikke om det var nødvendig 🥺

cjohansen07:12:21

Har forsøkt litt profilering, men fikk ikke så mye ut av det

cjohansen07:12:55

Jeg har en lang funksjon som jeg har lyst til å tyne litt mer ut av

cjohansen07:12:24

Får ca 2x på create node, uten at jeg helt ser hva som kan bli bedre. Lurer på om noe er overhead med immutable data

slipset07:12:17

Du slår jo opp (:renderer impl) en haug med ganger der?

slipset07:12:39

(hvis jeg er på rett sted)

slipset07:12:48

Og jeg sitter bare og leser koden, kjører den ikke.

cjohansen07:12:28

Ja, det er kanskje dumt?

cjohansen07:12:41

Jeg har tenkt at kompilatoren tar seg av sånt 😅

cjohansen07:12:48

Jeg har lite trening i å tune performance

slipset07:12:04

Det kan godt være at kompilatoren tar sånt.

cjohansen07:12:11

Lett å prøve

slipset07:12:11

Man må nesten bare prøve.

slipset07:12:24

Men, bruker du noe annet en :renderer fra impl ?

cjohansen07:12:03

Flytta på et tidspunkt :hooks inn i protokollen, men det ble helt feil, da må protokollen hjelpe algoritmen med å gjøre jobben sin

slipset07:12:44

https://github.com/cjohansen/replicant/blob/main/src/replicant/core.cljc#L210 du kunne vel ha gjort denne omvendt? i steden for å sjekke på om det du holder på med er hiccup, så kunne du sjekke om det var en string?

cjohansen07:12:30

Kan også være alt mulig annet rart

cjohansen07:12:43

tall, booleans, et map

cjohansen07:12:06

jeg trodde at det hiccup-greiene skulle koste mer enn det ser ut til å gjøre

cjohansen07:12:37

Denne kalles på alle "noder" i hiccup, men memoize på den hadde 0 effekt: https://github.com/cjohansen/replicant/blob/main/src/replicant/core.cljc#L165

cjohansen07:12:04

Der jeg vet det forsvinner for mye tid nå er i update-children hvor det gjøres for mange index-of-sjekker for å finne ut av om noder har flyttet seg. Gjorde to forsøk på å fikse det i går, men den funksjonen er lang og tung å jobbe med 😅

slipset07:12:49

https://github.com/cjohansen/replicant/blob/main/src/replicant/core.cljc#L212 sikkert bare småpirk, men du oppretter et nytt map her “alltid” for {:ns ns} antar at det er sjelden du har noen verdi i ns ?

❤️ 1
cjohansen07:12:35

Tar gjerne imot pirk!

cjohansen07:12:37

Skal fikse det

slipset07:12:38

https://github.com/cjohansen/replicant/blob/main/src/replicant/core.cljc#L279 returnerer du et map når du egentlig kunne klart deg med en boolean?

cjohansen07:12:21

Absolutt. Det henger igjen fra da løsningen sendte inn og returnerte tilstanden i "impl".

slipset07:12:16

Er run! raskere enn en loop/recur ?

cjohansen07:12:55

Spurte om det på #C03S1L9DN i går, de mente så. Jeg tror ikke jeg så de helt store forskjellene

cjohansen07:12:09

Dvs, jeg bytta fra doseq, som genererer masse kode

cjohansen07:12:48

Har ikke sammenligna den med loop, men run!/`reduce` skal være raskest for vektorer. Litt usikker på om alle stedene jeg bruker den er på vektorer.

slipset07:12:37

Spiller sikkert ikke noen rolle, men https://github.com/cjohansen/replicant/blob/main/src/replicant/core.cljc#L273 så trenger du ikke recur’e fordi du recur’er med new-c = nil, så du kommer alltid til samme sted?

slipset07:12:55

Så du kan ta en mer spesialisert path.

slipset07:12:39

antagelig noe a la det du gjør i linje 278

cjohansen07:12:11

Ja, den recur nil-saken hadde jeg tenkt til å fikse da jeg fiksa den andre. Men den trenger n og n-children, og sletting av noder er det koden bencher raskest på, så jeg lot den være

slipset07:12:25

Jeg hadde, sånn for første lesbarhetsskyld (har lært meg det nå) foretrukket en remove-hooks

slipset07:12:55

(jeg tror det er en remove-hook)

slipset07:12:07

(da kunne også register-hook blitt enkere?

cjohansen07:12:22

Det er ikke remove-hook, det er "legg til en hook for removal"

cjohansen07:12:53

Ingen ny vdom og eksisterende old vdom => unmount

slipset07:12:32

Den concat ’en her https://github.com/cjohansen/replicant/blob/main/src/replicant/core.cljc#L363 er vel også litt slitsom, i allefall for meg å lese.

cjohansen07:12:37

Kan samlokalisere register-hook og call-hooks, for det er sistnevnte som finner ut av det der

cjohansen07:12:57

Ingen som krangler på det @slipset 😂

cjohansen08:12:54

Jeg har som sagt prøvd å skrive den om to ganger... Vil over til å bare bruke index i vektorene, men har enn så lenge ikke lykkes

cjohansen08:12:40

Planen min er: 1. Ignorer alle posisjoner fra start hvor nodene er like, sånn at det blir raskere å appende til en lang liste 2. Finn ut på forhånd hvilke noder som har flytta seg med én n^2 loop 3. Slå opp flytteindekser under traversering Men flyttinga gjør det litt tricky

slipset08:12:12

Kunne du gjort en mellomting?

cjohansen08:12:15

Jeg tror det skal være mulig ja, men de to concatene du fant gjør det litt 🤯 - de etterligner flyttinga som foregår i dom-en

slipset08:12:19

Så lenge du ikke identifiserer en move, så er det enkelt å jobbe med index’er og så, hvis du identifiserer en move, så kan du velge den enklere, men tregere algoritmen?

slipset08:12:20

Litt sånn som her.

slipset08:12:50

(parse json strings er “lett og raskt” så lenge du ikke behøver å deale med escapes)

leifericf08:12:17

Jeg tror dette med ytelse avhenger veldig av domenet og hvorvidt det faktisk er en essensiell del av sluttbrukerens behov. Som tidligere teamleder for real-time 3D grafikkmotorteamet til Funcom i gamledager, når de hadde sin hjemmelagde motor, så jeg mye rart av C/C++, compiler-spesifikke triks, shader hacks og inline Assembly for å maksimere ytelsen. Samtidig som det måtte se råbra ut og helst kjøre på et bredt spekter av operativsystemer, CPU-er og GPU-er. Det var ofte vi måtte gjøre vanskelige avveininger mellom ytelse og det estetiske. Hva er "god nok" ytelse veid opp mot andre ting som brukeropplevelse, estetikk og teknisk kompleksitet er utrolig vanskelig.

💯 1
slipset08:12:43

Jepp, men jeg tror mange utviklere gjør det trade-off’et uten å gjøre det.

👍 1
cjohansen08:12:47

Interessant approach @slipset

slipset08:12:33

Den (approachen) er jo basert på at man som regel ikke har escapes i json-strings. Vet ikke hvor ofte move nodes opptrer i dom manipulering.

cjohansen08:12:46

Det som er interessant er at løsningen min er råkjapp på flytting. 3x enn React 😅

cjohansen08:12:26

Men koden gjør at andre use caser blir treigere (er ihvertfall teorien). Så ut fra det høres forslaget ditt veldig fornuftig ut.

cjohansen08:12:35

Kjører en benchmark nå med litt færre slenger-maps og map-oppslag

slipset08:12:18

var det vanskelig å gjøre benchmark greia?

slipset08:12:39

Leste litt fort på skrå, så ut som det var litt jobb 😕

slipset08:12:20

Tror jeg må overtale min kollega til å kjøre https://github.com/chriskr/uldu i den benchmarkinga (bare for å ha det som en benchmark).

cjohansen08:12:21

Har oppsettet klart nå, det tar litt tid, bare

cjohansen08:12:30

5min kanskje

cjohansen08:12:43

Ser ut til at alle tallene er litt bedre :star-struck:

cjohansen08:12:40

Kan selvfølgelig være dagsformen til maskinen min, men alle tallene er 5-10% bedre fra i går

slipset08:12:02

Det er jo bedre enn at de er 5-10% dårligere?

cjohansen08:12:13

Absolutt 😄

cjohansen08:12:20

De to røde boksene tror jeg handler om de concatene

cjohansen08:12:31

Eller, altså, den delen av koden

cjohansen08:12:08

Tusen hjertelig takk for at du leste gjennom 🙏

slipset08:12:57

Bare kos! Jeg hadde også vært interessert i en IRLish code review en gang. Jeg har jo ikke brukt noe tid på å forstå algoritmene (sier ikke at jeg kunne forbedret dem), men kanskje du kunne sett noe hvis jeg var en gummi and for deg.

cjohansen08:12:23

Ja, det hadde vært veldig trivelig å gått gjennom dette sammen, tenkte på det selv

cjohansen08:12:48

Det er slettes ikke sikkert at mine algoritmer er de beste, jeg er ikke ekspert på området. Har bare prøvd litt forskjellig.

cjohansen08:12:45

Jeg tar gjerne en runde på video om du er interessert. Jeg har betalt Tuple, så om du installerer den kan vi ta det over den - da kan man dele tastatur, tegne på skjermen osv.

cjohansen08:12:03

Fun fact: Tuple-abonnementet mitt kom opp til fornyelse i desember. Jeg var litt demotivert av å gå opp "få tilgang til software"-løypa i staten, og kikka litt rundt. Viser seg at Tuple sponser OSS-folk, så @U07FCNURX og jeg fikk sponset abonnement 😄

cjohansen08:12:31

Kult! Du er kanskje på jobb? Jeg har fri og er ledig nå og resten av dagen.

slipset08:12:12

Gi meg ti min?

leifericf08:12:46

Hvilke DOM-operasjoner tror vi det skjer mest av generelt? Det er kanskje vanskelig (eller nærmest umulig?) å svare på. Men hvis det kan besvares (eller estimeres?) kan det kanskje informere visse prioriteringer og avveininger.

cjohansen08:12:54

Sikkert noen som har undersøkt. Hvis du kan instrumentere et sånt bibliotek i en litt komplisert app burde du få noen innsikter.

👍 1
cjohansen08:12:24

Jeg kan ihvertfall finne ut av hvilke primitiver som brukes mest ved å instrumentere denne: https://github.com/cjohansen/replicant/blob/main/src/replicant/dom.cljs

leifericf08:12:46

Og kanskje det finnes noen triks for å gjøre om enkelte av de treigere operasjonene til en av de raskere operasjonene, om ikke i biblioteket så på brukersiden i praksis etter litt opplæring. Det gjorde vi ofte med 3D grafikkmotoren: vi "castet" om dyrere operasjoner til billigere operasjoner. Eksempelet til @U9MKYDN4Q på "replace all rows" med og uten nøkler fikk meg til å tenke på det. I Clojure kan det kanskje finnes noen overraskende ytelsesforskjeller mellom bruken av lists og vectors, for eksempel når man genererer eller leser "front-to-back" vs. "back-to-front."

👍 1
cjohansen11:12:07

Nå har @slipset og jeg hatt en veld trivelig sesjon på formiddagen, og tallene peker i riktig retning. 5-15% forbedring over hele fjøla:

💜 1
cjohansen11:12:26

Det kom en todo-liste ut av den sesjonen også 🙂

1
slipset11:12:20

Fortsatt litt irr med replace all rows

cjohansen11:12:19

Ja, den krever at jeg slåss med update-children

slipset11:12:34

Takk for commits og takk for en veldig hyggelig formiddag.

cjohansen11:12:50

Like så 😊

cjohansen11:12:34

Prøvde forøvrig å memoize komponentene. Det ga marginalt bedre tall, men forutsigbart nok økte minnebruken merkbart. Jeg er usikker på om det er verdt det

cjohansen11:12:08

Vent! Screenshottet over er etter forbedret parse-hiccup-symbol. Ved å også bytte om rekkefølgen på key- og tagname-sjekk i same? ser det sånn ut:

cjohansen11:12:45

Det er åpenbart mye å hente i å optimalisere hiccup-greiene

slipset11:12:06

Det vi vel også ser er at det brukes så godt som null tid på å herje med dom’en, noe som skulle indikere at det skulle kunne slurves noe mer i finregninga på om man skal herje med dom eller ei.

cjohansen11:12:45

Ja, det er et godt poeng. Nettleserene er nok godt optimaliserte.

slipset11:12:16

Uansett, nå tror jeg det jammen er på tide å stikke i bakken.

cjohansen11:12:33

Ja, jeg skal ut å måke 😅

1
leifericf12:12:55

Jeg har min siste dag på dette kontoret, med kun to andre kollegaer 🙂 Straks leverer jeg inn hardware og adgangskort og fyker i vei.

cjohansen12:12:06

Litt småtrist avslutning. Håper de gjorde stas på deg før jul 😊

leifericf12:12:39

Jepp! Hadde en liten avslitning avslutning før alle dro på ferie.

leifericf12:12:32

Kjøpte meg nettopp en ny beefy 14'' M3 MacBook Pro for å trøste litt, hehe

❤️ 3