Jak z WebGL przeszedłem do Wasm i DOM

Więc tak, pisałem sobie ten silnik 3D i cóż, okazało się, że im bardziej się rozrastał, tym więcej miałem problemów z długiem technicznym (zrobiłem coś, co wyglądało fajnie w teorii, ale w praktyce, żeby coś dodać, musiałem trochę pohakować silnik) oraz też zacząłem odczuwać problemy z wydajnością.

I tutaj na tym etapie zacząłem eksperymentować z użyciem WebAssembly - ponieważ w profilerze zobaczyłem, że dużo czasu CPU schodzi na liczenie macierzy, postanowiłem liczyć macierze w WebAssembly, używając Rust-a i biblioteki do macierzy pisanej w Rust.

I co się okazało? Moja "optymalizacja" nie przyniosła oczekiwanych rezultatów. Być może dlatego, że i tak w JS musiałem iterować po obiektach i masę rzeczy innych robić, a w Wasm tylko liczyłem macierze. Zbyt duża część silnika polegała na (z konieczności) kiepsko napisanym JS, że Więc pomyślałem, że może trzeba jeszcze więcej obliczeń wrzucić do Wasm, najlepiej całe drzewko sceny tam zapisywać i robić tam wszystko, w JS tylko renderować. Problem jednak, że przy istniejącej architekturze ciężko byłoby wydzielić to drzewko sceny. Nie myślałem za wczasu, że będę chciał użyć WebAssembly do optymalizacji części apki!

Więc na tym etapie zrodził mi się pomysł - przepisać cały silnik na Rust (a przynajmniej dużą część), żeby sprawdzić, czy będzie szybciej działać. Żeby to osiągnąć to oczywiście:

  • zacząłem się uczyć Rusta
  • zacząłem przepisywać prawie cały silnik od nowa, ale nie w Rust, tylko w JavaScript

Konieczność nauki Rusta jest oczywista. Ale czemu zacząłem przepisywać silnik nie już na Rusta, ale na JavaScript jeszcze raz? Z prostego powodu - moim celem jest sprawdzenie, czy silnik pisany w WebAssembly będzie szybszy niż taki sam silnik pisany w JS. Więc potrzebuję mieć dwie mniej więcej takie same implementacje - jedną pisaną w JS, drugą w Wasm, i dopiero wtedy będę mógł porównać i sprawdzić, czy faktycznie Wasm się opłaca użyć, czy może jest przereklamowany (bo jakoś dostępne w necie benchmarki WebAssembly nie pokazują wcale tej jego super mocy. Czasami nawet rzeczy pisane w Wasm są wolniejsze od tych w JS). Innymi słowy teraz mam napisaną taką implementację

Czyli big ball of mud - napakowane obiekty różne. Ciężko określić, czy nie jest to wydajne, bo są jakieś obliczenia, czy może przez kiepską architekturę. Dlatego teraz przepisuję to w JS na taką architekturę:

Tylko teraz piszę tak, żeby dało się to przeportować w prosty sposób 1:1 do WebAssembly. I np. nie używam stringów tylko liczby. Bo przedtem każdy obiekt miał typ w stringu (np. "quad"), to teraz ma typ w postaci liczby. Tym sposobem będzie łatwiej pobrać dane z Wasm do JS. Plus zamiast robić drzewko w postaci drzewa obiektów JSowych, to trzymam całe drzewko sceny jako tablicę obiektów (żeby po przeportowaniu na Rust dało się pobrać dane całej sceny w jednym liniowym kawałku pamięci).

Ale tak, pisząc sobie ten silnik 3D nagle mnie naszło, że może wcale nie silnik 3D chcę zbudować, tylko własny framework taki do robienia normalnego DOM? Więc teraz w tym kierunku robię research. Plus szukam informacji o tym, jak zrobić własny kompilator czy parser, bo jeszcze mi się idea pojawiła, żeby zrobić własny system szablonów i minijęzyk programowania. Ale to zobaczymy. Szybko mi się pomysły zmieniają, ale jednocześnie te same pomysły wracają do mnie przez lata. Niektóre pomysły po prostu są zbyt trudne, żeby je zaimplementować dobrze w pierwszej iteracji. Niektóre pomysły są źle ukierunkowane. Niektóre wymagają więcej wiedzy itp. W każdym razie coś zrobię i będzie to fajne. A co zrobię, to niech będzie niespodzianką.

Komentarze

Popularne posty z tego bloga

Dlaczego nie da się nadgonić frontendu

Absurdy Rekrutacji 2023

Przygody juniora (1)