Skrivet av klk:
Det är inte bättre. Enda anledningen till att jag tänkte testa är att andra utvecklare i Rust är så entusiastiska. Samtidigt är koden de skriver inte speciellt bra om det inte handlar om deklarativ kod. Lite som när man ser yngre spelprogrammerare, de är också helt värdelösa i arkitektur och skriver illa. Man vill få fram sitt spel och är inte jätteintresserad av koden som skrivs.
Jag är själv typiskt entusiast programmerare (hobby och yrke). Det skiljer exempelvis gruppen mot C# och Java. De som skriver kod i dessa språk accepterar i princip vad som helst, det är bara ett yrke. Utvecklare i Rust har mycket mer driv.
Då du aldrig använt Rust gör massa fel direkt felaktiga antaganden.
T.ex. så postade du denna länk längre upp
https://linearb.io/blog/message-chains-code-smell
och hävdade att de som kodar i Rust ofta skapar "message chains". Nu är det tekniskt möjligt att göra sådant i Rust, men det är inte ett språk som explicit stödjer OOP och finns därför inget som tvingar en att trycka in allt i klasser likt C#/Java. Idiomatisk Rust innehåller inte "message chains".
Däremot, från din egen länk, så är det många som blandar ihop "message chains" (som den artikeln anser är "dåligt") med "pipeline-style" (som artikeln anser är "bra"). Pipeline-style är extremt vanligt i Rust-kod, då främst i form av filter/map/reduce/etc.
Än mer är detta trevligt då kod skriven på det sättet i Rust kan i många lägen väldigt enkelt ändras (minimal kodändring) så den effektivt utnyttja multipla CPU-kärnor, via ramverk som Rayon. C++ har ett embryo till liknande stöd i standardbiblioteket i form av execution policy, men i nuläget är Rust/Rayon både mognare, ger i nästan alla lägen bättre presterande resultat och långt enklare att använda på "rätt sätt" (i.e. inga data-race).
Skrivet av klk:
När jag ändå håller på kan jag kanske ta något som jag tror är förståeligt utan att man behöver känna till programmering
En cache line på x86 är 64 bytes, samma på de flesta ARM processorer, har för mig att apple har arm processorer med en cache line på 128 bytes.
Alla systemspråk samt Java, C#, Go, m.fl. har alla det relevanta stödet för att undvika prestandaproblem som false-sharing i de fall man delar data mellan trådar på korrekt sätt.
Utöver det är det rätt lite man behöver bry sig om cache-line storlek idag. Om man gör saker som är extremt prestandakritiskt är det i så fall idag mer relevant att tänka på page-gränser som väldigt länge "alltid" var 4k, men som på ARM64 allt oftare är 16 kB (kan vara 4, 16 eller 64 kB och är upp till OS att välja vilken storlek en viss process har, MacOS kör 16 kB och Linux har allt mer börjat gå till 64 kB på servers då enbart 4->64 kB page storlek kan ge 10-20 % bättre prestanda i "minnes-tunga" laster).
Skrivet av klk:
Processorer tycker också om att hitta data på jämnt delbara adresser med siffror som 4,8,16 och så vidare.
90-tals CPU, visst. En modern CPU har en långt mer avancerad access-pattern detektor än så...
Så länge din stride är förutsägbar spelar dess värde rätt liten roll. Det relevanta att ta med sig från det är: en array är betydligt snabbare än en hashmap, trots att båda är O(1).
INGET här är något som ger C++ en unik fördel.
Skrivet av klk:
Förutom att ovanstående så älskar också processorer förutsägbarhet. Processorer gissar ofta vart nästa minne ligger och vet utvecklare om hur processorn gissar eller kan hjälpa processorn på traven, då kan processorn arbeta så mycket snabbare.
Exakt. Enda som möjligen man kan "hjälpa" med är att försöka hålla working-set på så få "pages" som möjligt. TLB-L1 är mer prestandakritisk i moderna CPUer än L1-cache för data/kod.
Skrivet av klk:
När data placeras "rätt" fungerar också SIMD instruktioner bättre. Därför kan kod skriven i C++ se lite kryptisk ut, inte jättekonstig men samtidigt vara nästan 10 gånger snabbare än kod skriven i exempelvis C#.
Så här krångligt är det att använda SIMD i C# för de riktigt vanliga fallen
var a = new Vector3(1, 2, 3);
var b = new Vector3(4, 5, 6);
var dotProduct = Vector3.Dot(a, b);
var crossProduct = Vector3.Cross(a, b);
Detta blir "handoptimerad" SIMD för de plattformar som .NET-runtime stödjer. Och tillskillnad från C++ där man måste välja om det ska vara SSE, AVX, NEON eller SVE2 etc när man kompilerar kommer detta välja "bästa val" när programmet körs (vid JIT).
Så i praktiken (är möjligt att skriva kod som väljer vid runtime även för C++, något som ramverk likt ISPC kan göra) kan just sådant vara snabbare hos plattformar som använder JIT.