This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2023-12-29
Channels
- # aleph (1)
- # announcements (5)
- # beginners (21)
- # cider (4)
- # clojars (1)
- # clojure (39)
- # clojure-europe (5)
- # clojure-norway (133)
- # clojurescript (5)
- # datomic (27)
- # exercism (2)
- # gratitude (4)
- # humbleui (21)
- # hyperfiddle (10)
- # integrant (16)
- # introduce-yourself (1)
- # lsp (17)
- # matrix (1)
- # nbb (10)
- # overtone (5)
- # polylith (21)
- # re-frame (6)
- # squint (3)
- # tools-deps (22)
- # yamlscript (102)
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.
Dumdom er veldig mye treigere ja! Har aldri tuna performance på den, men heller ikke opplevd store problemer :man-shrugging:
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.
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.
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)
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.
Og så blir det problematisk hvis raskest medfører komplisert kode utenfor biblioteket.
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 😅
Denne Implementasjonen har bare ett atom som brukes til å spare på hooks som skal kalles
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 🥺
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
Flytta på et tidspunkt :hooks
inn i protokollen, men det ble helt feil, da må protokollen hjelpe algoritmen med å gjøre jobben sin
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?
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
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 😅
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
?
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?
Absolutt. Det henger igjen fra da løsningen sendte inn og returnerte tilstanden i "impl".
https://github.com/cjohansen/replicant/blob/main/src/replicant/core.cljc#L335 ser tung ut
Spurte om det på #C03S1L9DN i går, de mente så. Jeg tror ikke jeg så de helt store forskjellene
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.
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?
useless use of map ? https://github.com/cjohansen/replicant/blob/main/src/replicant/core.cljc#L284
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
Jeg hadde, sånn for første lesbarhetsskyld (har lært meg det nå) foretrukket en remove-hooks
eksempelvis https://github.com/cjohansen/replicant/blob/main/src/replicant/core.cljc#L309
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.
Kan samlokalisere register-hook
og call-hooks
, for det er sistnevnte som finner ut av det der
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
Right, for i https://github.com/cjohansen/replicant/blob/main/src/replicant/core.cljc#L255-L256 burde du egentlig kunne klart deg med indexer?
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
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
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?
https://github.com/clojure/data.json/blob/master/src/main/clojure/clojure/data/json.clj#L176
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.
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.
Men koden gjør at andre use caser blir treigere (er ihvertfall teorien). Så ut fra det høres forslaget ditt veldig fornuftig ut.
Tror jeg må overtale min kollega til å kjøre https://github.com/chriskr/uldu i den benchmarkinga (bare for å ha det som en benchmark).
Kan selvfølgelig være dagsformen til maskinen min, men alle tallene er 5-10% bedre fra i går
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.
Det er slettes ikke sikkert at mine algoritmer er de beste, jeg er ikke ekspert på området. Har bare prøvd litt forskjellig.
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.
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 😄
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.
Sikkert noen som har undersøkt. Hvis du kan instrumentere et sånt bibliotek i en litt komplisert app burde du få noen innsikter.
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
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."
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:
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
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:
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.