Posty

Wyświetlam posty z etykietą rust

rdzawe łańcuchy(1): z węża do wielbłąda

Hej! Będzie to seria wpisów (a w zasadzie już jest to seria wpisów, bo już to zacząłem pisać). W każdym razie będę tu omawiał różne ciekawostki jeśli chodzi o stringi w Ruście. Np. dzisiaj omówimy sobie, w jaki sposób można napisać funkcję, która konwertuje takiego stringa "foo_bar_baz" na takiego: "fooBarBaz" Czyli zamieniamy z notacji snake case na camel case. Taka zabawa. A więc zaczynamy. napiszemy sobie funkcję main oraz sygnaturę naszej funkcji: fn main() { println!("{}", to_camel_case("foo_bar_baz_qwerty")); } fn to_camel_case(s: &str) -> String { } Jak widać jest to funkcja, która pobiera wycinek stringa ( string slice ) i zwraca stringa o typie String (chodzi o to, że potrzebujemy stworzyć nowego stringa i go zaalokować na starcie, dlatego zwracamy String, a nie &str). Dalej, stworzymy również wspomnianego już Stringa i go zwrócimy (na razie jest pusty). Możemy to zrobić poprzez `return out;`. Ale powiedzmy,...

Fajerwerki, które uczą

Robię projekt w Rust. Będą fajerwerki, mówię mam. Dosłownie. To są fajerwerki. Pisane w Rust, skompilowane do WebAssembly i przez JSa przesyłane do WebGLa. I się renderują. Później powrzucam screeny, na razie musicie mi uwierzyć. Anyway, czego się nauczyłem do tej pory tworząc ten projekt? iteratory w Rust mogą być szybsze od zwykłej pętli iterującej po liczbie i . Ogólnie miałem taki problem, że iterując jednocześnie po dwóch tablicach (iteracja po i i odniesienie się do elementów z dwóch tablic o tym indeksie), wydajność takiego kodu była taka sama jak wydajność analogicznego kodu w JS. Jednak jak poszedłem po rozum do głowy i użyłem iter() oraz zip() żeby połączyć dwa iteratory, nagle zaczęło być szybciej. Okazuje się, że iteratory w Rust są tanie w użyciu. bindingi wasm-bindgen potrafią wyeksportować struktury z Rusta jako klasy JS. Więc można od strony JS po prostu robić new Foo i się utworzy instancja klasy z metodami. To jest nowe dla mnie, bo mogę utworzyć taką klasę i ...

Zardzewiała dziwność asynchroniczności

Uczę się o async/await w Rust. I to jest śmiesznie zrobione, że "futures" (rustowy odpowiednik promisów) się nie uruchamiają same! bo jak wywołasz funkcję asynchroniczną w JS, to ona zwraca promise i się uruchamia od razu. A w Rust tak nie ma! Nic się nie dzieje. Jak wywołasz funkcję asynchroniczną, to dostajesz "future" (tak jak w JS dostajesz "promise"), ale nic się nie uruchomi samo! No ale JS daje obietnice bez pokrycia, a Rust to język dla osób odpowiedzialnych, więc samemu trzeba zadbać o swoją przyszłość, tzn. o future. Samemu uruchamiasz w specjalny sposób, bo Rust ma być wydajnym językiem, a zrobienie tak, jak w JS, że gdzieś tam jest odgórnie ustalona pętla eventów, ktora odpala te promisy, byłoby narzutem wydajnościowym, na który nie wszyscy mogą sobie pozwolić. Jest o tym prezentacja Steve'a Klabnika: The Talk You've Been Await-ing for No i jest trochę zachodu w tym, żeby to zrobić w czystym Rust, więc powstały biblioteki takie ...

Jak z WebGL przeszedłem do Wasm i DOM

Obraz
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...