Comments (8)
Somewhat terse response...I presume you are saying that converting from utf8 to utf16 and vice versa within Javascript is sufficiently performant. However, though that may be the case and indeed my suggestion might amount to premature optimization; nonetheless, avoiding the need for conversion in the first place seems inherently more performant. 😀
Sorry, I was trying to get something out in between meetings before I forgot. Should have read that again before I sent it. I hadn't tried that before. I meant it doesn't appear to make things faster. It seemed promising so I created a benchmark. I would have expected converting a utf16 array to a JavaScript string to be faster because you don't have to change encodings. If you run the benchmark in my last message it seems to be slower instead. I'm not entirely sure why? Maybe the uft16 version is just copying more memory?
Part of this is due to the types of string operations we do. I suspect that adding two strings already in JavaScript would be faster than adding them in rust and then converting the arrays to a JavaScript string but most of Dioxus' code would require the strings to start in rust code so it is difficult to avoid the conversation.
We do a few things to be faster with string conversion:
- We dynamicly cache the most recently used string for elements, attributes, etc by hashing the pointer (as opposed to a prebaked list like this PR adds)
- We combine all strings on the rust side into one long string and then only call decode once in the JavaScript side. This is the main thing that sledgehammer-bindgen does faster
- We use hyristics to choose a string decoding algorithm
from dioxus.
This is an interesting issue to research. Its important to define 'good' performance and goals ahead: is it average or worst-case?
I've traced the example projects and some of my own pet projects. Almost all good candidates (by most frequent appearance) for interning already were part of the builtin predefined cache. This is generally because applications have few repetitive content (text and class names). I assume, that having a smart automatic interning algorithm would reduce overall performance.
However the rules above don't apply for applications with large lists, tables and highly repetitive content. Given, that we'll be tracing DomEdits, we can tell tags and attributes apart from user text and values. The former are probably already interned, the latter require more analysis. And this is an opportunity for reducing worst case performance (no predictions on average), so the main goal would be high adaptiveness and flexibility. For example, detecting that we're in the middle (or better at the start) of rendering a large table with repetitive text and styles.
web-sys is already looking up every string in a hashmap if string interning is enabled (if only we could supply it with pre-calculated hashes 😢).
A good approach with high adaptiveness would be having a sliding window counting the most frequent string among the last X requests. As soon as a string appears more than 2 or 3 times, it should be interned. And then easily be replaced if its not in the window. A bloom filter is great for tracking large amounts of data in a compact manner, but doesn't tell let you detect rapid changes or delete elements from it. I'll experiment around before giving any detailed results.
from dioxus.
This is an interesting issue to research. Its important to define 'good' performance and goals ahead: is it average or worst-case?
I've traced the example projects and some of my own pet projects. Almost all good candidates (by most frequent appearance) for interning already were part of the builtin predefined cache. This is generally because applications have few repetitive content (text and class names). I assume, that having a smart automatic interning algorithm would reduce overall performance.
However the rules above don't apply for applications with large lists, tables and highly repetitive content. Given, that we'll be tracing DomEdits, we can tell tags and attributes apart from user text and values. The former are probably already interned, the latter require more analysis. And this is an opportunity for reducing worst case performance (no predictions on average), so the main goal would be high adaptiveness and flexibility. For example, detecting that we're in the middle (or better at the start) of rendering a large table with repetitive text and styles.
web-sys is already looking up every string in a hashmap if string interning is enabled (if only we could supply it with pre-calculated hashes 😢).
A good approach with high adaptiveness would be having a sliding window counting the most frequent string among the last X requests. As soon as a string appears more than 2 or 3 times, it should be interned. And then easily be replaced if its not in the window. A bloom filter is great for tracking large amounts of data in a compact manner, but doesn't tell let you detect rapid changes or delete elements from it. I'll experiment around before giving any detailed results.
It's a very exciting problem! We can do a lot of work to bridge the gap between Rust and JS frameworks until WASI types are supported and UTF8 JS strings are accepted naturally.
Our DomEdits are a tad naive in recognizing lists... hence why template support would be interesting.
I would love to see some prototypes of different heuristics. It might be worth wiring up the few benchmarks we have into CI/CD to get a sense of performance on every push and plot that over time.
Pre-hashing, bloom filters, tries, and other techniques would be very interesting to explore and I'd love to see any prototypes you might come up with. Hopefully the string cache code is simple enough to root around in.
from dioxus.
This is a somewhat solved problem with templates now. We have a fixed list of strings and then the templates are always made once.
from dioxus.
Any reason why you didn't simply create or use a utf16 crate such as utf16string
?
Granted, the non-web platforms use utf8 but could that difference be resolved via a trait
or type
alias?
from dioxus.
Any reason why you didn't simply create or use a utf16 crate such as
utf16string
?Granted, the non-web platforms use utf8 but could that difference be resolved via a
trait
ortype
alias?
It doesn't appear to be the case that converting from a utf16 string to a JavaScript string is faster https://jsbench.me/ptllv2ek5d/1. Sledgehammer bindgen helps with string conversion
from dioxus.
Somewhat terse response...I presume you are saying that converting from utf8 to utf16 and vice versa within Javascript is sufficiently performant. However, though that may be the case and indeed my suggestion might amount to premature optimization; nonetheless, avoiding the need for conversion in the first place seems inherently more performant. 😀
It would also be a great demonstration and exploitation of Rust fantastic trait based abstraction mechanism.
In any event, you know best. I am really a novice. Thanks for your attention 🙂.
from dioxus.
Perhaps I was nieve in thinking that the Javascript runtime could accept the byte array as a proper reference to a utf16 string without decoding or other gymnastics. If that were possible and it didn't perform any subsequent reallocation then I expect performance would be better. Of course, in the general case we would creating Javascript types in the interface buffer and perhaps bumping the specification of WASM, something that's out of scope.
Thanks again for your attention.
from dioxus.
Related Issues (20)
- dx new in existing multicrate workspace HOT 1
- `dx build --release` doesn't read the `[profile.release]` table from `Cargo.toml` (`strip` doesn't work) HOT 10
- Route order matters between url string and enum fields
- Add ability to configure "always on/pin to top" option for the Dioxus Desktop HOT 3
- Dynamic rendering unresponsive for if-else-expressions where expressions are Fragments
- Shorthand notation breaking rsx! macro with conditional rendering
- `rustflags` in `./cargo/config.toml` being ignored HOT 2
- use_callback should take a closure that accepts an argument HOT 1
- Call `.into()` automatically for the default value when deriving `Props`
- use of unstable library feature 'proc_macro_byte_character' HOT 1
- Dioxus CLI MSRV
- live reload doesn't work when just modifying the css file HOT 2
- Assigning a port number when using `dx serve --port [number]` on fullstack is not respected. HOT 2
- Ctrl/cmd click does not open in a new tab/window
- Dioxus-cli ignores env variables in `.cargo/config.toml` HOT 2
- pointermove events on Windows crash with InvalidType HOT 3
- [Desktop] Hot reloading does not work in the "tailwind" sample
- question: custom rendering to arbitrary wayland surface
- Hydration error when using use_server_future in certain contexts in Fullstack
- Docs have a couple outdated examples
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from dioxus.