WEBVTT

00:00.000 --> 00:13.000
We're going to get started, but how to lose weight?

00:13.000 --> 00:15.000
I'm going to put your mic on.

00:15.000 --> 00:16.000
It is on.

00:16.000 --> 00:17.000
Yep.

00:17.000 --> 00:18.000
You can hear me?

00:18.000 --> 00:19.000
Yes.

00:19.000 --> 00:24.000
Hello, everyone.

00:24.000 --> 00:27.000
I'm up all as well, Terry.

00:27.000 --> 00:33.000
I work at Vullment Automation, which is a Finnish national or global company.

00:33.000 --> 00:42.000
I'm working on a software architect and a programmer for a browser-based UI platform

00:42.000 --> 00:44.000
for running factories, basically.

00:44.000 --> 00:47.000
So if I make a mistake, then like millions burn in a day.

00:47.000 --> 00:48.000
It's fun.

00:48.000 --> 00:51.000
So I'm a TypeScript developer by day.

00:51.000 --> 00:55.000
I'm acquiring an open source enthusiast and albatross.

00:55.000 --> 00:59.000
I'm a data-oriented design-seller, which you might see very soon.

00:59.000 --> 01:03.000
If you've not heard of data-oriented design, I'm not going to explain,

01:03.000 --> 01:05.000
but maybe you'll kind of get it anyway.

01:05.000 --> 01:09.000
And I'm developing the Nova JavaScript engine in my free time.

01:09.000 --> 01:13.000
Written in Rust with data-oriented design principles in mind,

01:13.000 --> 01:16.000
which you will maybe also see a bit about here.

01:16.000 --> 01:18.000
So losing weight.

01:18.000 --> 01:20.000
What do I mean by weight?

01:20.000 --> 01:25.000
First of all, whatever I mean, this is supposed to be like fun and like whimsical.

01:25.000 --> 01:30.000
But mostly, I mean, the amount of memory your program uses at runtime.

01:30.000 --> 01:33.000
That's what we usually think about.

01:33.000 --> 01:37.000
Though, remember, your code is also weight.

01:37.000 --> 01:41.000
Get sent to the client or even if you're in no JS or something,

01:41.000 --> 01:44.000
it actually gets saved on the disk.

01:44.000 --> 01:49.000
Also, if you write horrible, horrible code,

01:49.000 --> 01:53.000
and you make your program so complex that nobody can understand.

01:53.000 --> 01:55.000
That is also weight.

01:55.000 --> 02:02.000
The complexity of your program and the context knowledge required to work with it is also weight.

02:02.000 --> 02:07.000
And I posit that for any program there exists an ideal weight.

02:07.000 --> 02:13.000
And this is kind of like a mix between the three kinds of weights there.

02:13.000 --> 02:16.000
You can take your own pick, like which one do you prefer.

02:16.000 --> 02:21.000
I'm more of the, like, take out memory, increase the others,

02:21.000 --> 02:23.000
but not by too much.

02:23.000 --> 02:28.000
So I'm going to talk about losing weight as in approaching the ideal memory weight,

02:28.000 --> 02:33.000
without ballooning the rest over much.

02:33.000 --> 02:36.000
Luckily, we can calculate the ideal memory weight.

02:36.000 --> 02:40.000
How many of you have heard of Shannon entropy?

02:40.000 --> 02:44.000
How many of you have heard of succinct data structures?

02:44.000 --> 02:47.000
I heard about them yesterday, and I was like, I've never heard of that.

02:47.000 --> 02:50.000
Oh, oh, oh, I know what those are, okay.

02:50.000 --> 02:54.000
Basically, Shannon entropy, which I will not explain,

02:54.000 --> 03:01.000
but it is the amount of surprisingness in your data.

03:01.000 --> 03:04.000
How surprising is your data? That is Shannon entropy.

03:04.000 --> 03:10.000
Or another way to say it is how many yes or no questions must be answered before the data is understood.

03:10.000 --> 03:16.000
For, for example, you have a stream of bits where every 500 bits,

03:16.000 --> 03:20.000
there is one non-zero value.

03:20.000 --> 03:25.000
So it's always zero except like one in 500 on average.

03:25.000 --> 03:29.000
I asked one question, are the next 500 bits all zero?

03:29.000 --> 03:32.000
If the answer is yes, I have understood the data,

03:32.000 --> 03:38.000
and now we can also say that the amount of Shannon entropy in that data is roughly,

03:38.000 --> 03:42.000
maybe one bit.

03:42.000 --> 03:48.000
So Shannon entropy gives you the amount of bits of information that your data holds.

03:48.000 --> 03:52.000
Not the amount of memory that you use to hold it,

03:52.000 --> 03:57.000
just the amount of data there is, the amount of information there is in that.

03:57.000 --> 04:02.000
All right. Here are some JavaScript values.

04:02.000 --> 04:07.000
Always the same size regardless of what kind of data it holds,

04:07.000 --> 04:10.000
kind of on the stack anyway.

04:10.000 --> 04:13.000
So it's four bytes in Chrome and eight bytes everywhere else,

04:13.000 --> 04:17.000
unless you are in a 32-bit machine, hopefully not anymore.

04:17.000 --> 04:23.000
And Boolean and small integers, or in some engines, all numbers,

04:23.000 --> 04:28.000
are already held in that four or eight bytes directly.

04:28.000 --> 04:34.000
But then any object, any array, any symbol, so-and-so forth,

04:34.000 --> 04:38.000
those also have data on the heap.

04:38.000 --> 04:42.000
And you can see those values taken from node and Chrome there.

04:42.000 --> 04:46.000
Basically, it's always one header reference,

04:46.000 --> 04:49.000
and that header reference is now the size of a JavaScript value,

04:49.000 --> 04:53.000
because the JavaScript value is the size of a reference in the engine.

04:53.000 --> 04:57.000
Plus than some data, like a number is header reference,

04:57.000 --> 05:01.000
that's four or eight bytes, plus eight bytes of double data,

05:01.000 --> 05:03.000
so 16 bytes or 12 bytes.

05:03.000 --> 05:08.000
And as we go down here, you can see that an object is 24 or 12 bytes,

05:08.000 --> 05:12.000
node or Chrome, but when you go to array buffer,

05:12.000 --> 05:20.000
or uintake, array, they're 96 or 52 bytes, and 104 or 60 bytes.

05:20.000 --> 05:23.000
Huge objects, and those are empty.

05:23.000 --> 05:26.000
You have no data, no information in those.

05:26.000 --> 05:29.000
It's just the object itself.

05:29.000 --> 05:33.000
Okay, so how to actually lose weight?

05:33.000 --> 05:38.000
Well first, the previous talk mentioned oversharing.

05:38.000 --> 05:41.000
Don't overshare with your client.

05:41.000 --> 05:43.000
Remove the things you don't need.

05:43.000 --> 05:46.000
The things you don't need in the client that are never used,

05:46.000 --> 05:48.000
so it should be removed.

05:48.000 --> 05:51.000
This is like, obviously, kind of done in simple,

05:51.000 --> 05:53.000
but yes, this does happen.

05:53.000 --> 05:56.000
I removed a lot of stuff recently.

05:56.000 --> 06:00.000
Second of all, get rid of Booleans.

06:00.000 --> 06:03.000
You want mate?

06:03.000 --> 06:07.000
Booleans are really nice, really cool, in many ways.

06:07.000 --> 06:11.000
Very convenient, but it's four or eight bytes.

06:11.000 --> 06:14.000
This is a store one bit, one bit.

06:14.000 --> 06:17.000
That is, like, if you're in Chrome,

06:17.000 --> 06:21.000
where the size of a value is small, smaller than elsewhere,

06:21.000 --> 06:25.000
that's 3% of memory used at all.

06:25.000 --> 06:27.000
3%.

06:27.000 --> 06:31.000
Like, you have 64 gigabytes of RAM in your computer,

06:31.000 --> 06:35.000
and now I'm going to say, hey, you're allowed to use four gigabytes of it.

06:35.000 --> 06:36.000
How about?

06:36.000 --> 06:38.000
No, please no.

06:38.000 --> 06:41.000
So we want to get rid of Booleans, where we can.

06:42.000 --> 06:46.000
We want to use context knowledge to get rid of stuff

06:46.000 --> 06:51.000
or optimize stuff down to smaller sizes, where we can.

06:51.000 --> 06:55.000
And we want to be able to choose appropriate data sizes or

06:55.000 --> 06:57.000
storages for data.

06:57.000 --> 07:00.000
Whenever we can, based on context knowledge,

07:00.000 --> 07:03.000
based on the system that you're working with.

07:03.000 --> 07:08.000
You've been working on that program for, like, ten years at this spot, right?

07:08.000 --> 07:10.000
How many of you have been working for ten years in the same thing?

07:10.000 --> 07:12.000
Yeah, I know you're there.

07:12.000 --> 07:15.000
You know exactly what kind of data there is in the system.

07:15.000 --> 07:18.000
You can use that context knowledge.

07:18.000 --> 07:21.000
And you want to get rid of the heap headers,

07:21.000 --> 07:24.000
and actually objects, mostly, or entirely,

07:24.000 --> 07:26.000
if you can at all.

07:26.000 --> 07:29.000
Now, this is starting to sound a bit weird, like,

07:29.000 --> 07:31.000
wait, JavaScript without objects, like,

07:31.000 --> 07:33.000
what are you talking about?

07:33.000 --> 07:36.000
Struct of arrays is what I'm talking about.

07:36.000 --> 07:37.000
Yeah.

07:37.000 --> 07:40.000
This is the data oriented design side here.

07:40.000 --> 07:42.000
If you go structure of arrays,

07:42.000 --> 07:46.000
IE, you take your group of objects,

07:46.000 --> 07:49.000
and you turn it into one object which has multiple arrays,

07:49.000 --> 07:52.000
or type arrays, or maps sets.

07:52.000 --> 07:55.000
You can use context knowledge to store

07:55.000 --> 07:59.000
only the amount of data that you absolutely need.

07:59.000 --> 08:01.000
And you can get rid of booleans.

08:01.000 --> 08:03.000
Okay.

08:03.000 --> 08:05.000
Let's look at code.

08:05.000 --> 08:07.000
Now, this will be fun.

08:07.000 --> 08:11.000
I will have to try and find how to get my code edited back here.

08:11.000 --> 08:13.000
Where did you go, man?

08:13.000 --> 08:15.000
Where did I put you?

08:17.000 --> 08:18.000
Okay.

08:18.000 --> 08:20.000
I have lost my code editor.

08:20.000 --> 08:21.000
That's good.

08:25.000 --> 08:28.000
Now, I need to go to losing weight.

08:29.000 --> 08:32.000
Only come on.

08:36.000 --> 08:38.000
There we go.

08:38.000 --> 08:40.000
Now, that's much better.

08:40.000 --> 08:46.000
I have way too many code examples here.

08:46.000 --> 08:49.000
And unfortunately, I'm going to pick the simplest one,

08:49.000 --> 08:51.000
which is not real code.

08:51.000 --> 08:53.000
I have an actual real example,

08:53.000 --> 08:55.000
but I wouldn't have the time to go through it.

08:55.000 --> 08:59.000
So I'm going to give you a done simple example of what

08:59.000 --> 09:01.000
array of struts, the structure of arrays transforms.

09:01.000 --> 09:06.000
I mean, what kind of things you can do here to optimize.

09:06.000 --> 09:10.000
So I have here an object, component object.

09:10.000 --> 09:14.000
Some kind of retained mode UI stuff.

09:14.000 --> 09:16.000
There's a type, so this component,

09:16.000 --> 09:18.000
no, obviously there are many types of objects.

09:18.000 --> 09:22.000
This component apparently knows what type of object is.

09:22.000 --> 09:25.000
There's an enabled Boolean, which somehow, I guess,

09:25.000 --> 09:29.000
takes the component out of the whole UI maybe.

09:29.000 --> 09:33.000
Hovered, selected, is route with height, parent, children.

09:33.000 --> 09:36.000
Seems fairly standard, right?

09:36.000 --> 09:40.000
We have a component pretty much like this.

09:40.000 --> 09:43.000
Oh, yeah, and then there's this scope name here.

09:43.000 --> 09:47.000
This is going to be fun kind of two-part identifier.

09:47.000 --> 09:50.000
So path hierarchical path to a container,

09:50.000 --> 09:54.000
and then a unique name within that container.

09:54.000 --> 09:56.000
Remember that.

09:56.000 --> 09:59.000
And as we see, there's parent and children.

09:59.000 --> 10:02.000
So this is a hierarchy of components.

10:02.000 --> 10:04.000
IE, it's a group.

10:04.000 --> 10:09.000
Somehow a group of components, which form a larger set.

10:09.000 --> 10:14.000
This is not an array of objects right now,

10:14.000 --> 10:17.000
but we can still actually think of it as an array of objects.

10:17.000 --> 10:22.000
It's just structured in this tree structure or a hierarchy structure.

10:22.000 --> 10:26.000
And we can turn that into an array of objects.

10:26.000 --> 10:29.000
First, I'm going to get rid of some Boolean's.

10:29.000 --> 10:32.000
Or actually even before that, I'm going to get rid of something I don't need.

10:32.000 --> 10:34.000
Is route Boolean there?

10:34.000 --> 10:36.000
You didn't need it, did you?

10:36.000 --> 10:39.000
Your route, if your component is a route or not,

10:39.000 --> 10:42.000
is decided by it having a parent.

10:42.000 --> 10:44.000
Why did you have that Boolean there?

10:44.000 --> 10:47.000
You probably added it because it was convenient, right?

10:47.000 --> 10:48.000
Yes.

10:48.000 --> 10:50.000
I can check it like this, right?

10:50.000 --> 10:51.000
Nice.

10:51.000 --> 10:52.000
Yeah.

10:52.000 --> 10:53.000
Let's get rid of that.

10:53.000 --> 10:57.000
But then, the Enabled Boolean.

10:57.000 --> 11:01.000
That's one bit of information in each object,

11:01.000 --> 11:03.000
costing you four or eight bytes.

11:03.000 --> 11:05.000
It adds up.

11:05.000 --> 11:08.000
When you have thousands of these, it really adds up.

11:08.000 --> 11:10.000
So what we can do instead,

11:10.000 --> 11:17.000
is that we split the Enabled and disabled components from one another already at a higher level.

11:17.000 --> 11:22.000
We don't have any disabled components in the hierarchy at all.

11:22.000 --> 11:26.000
Obviously, maybe in your case, the components actually,

11:26.000 --> 11:29.000
they need to retain their position in the hierarchy,

11:29.000 --> 11:34.000
and they need to kind of know if they're enabled or disabled,

11:34.000 --> 11:36.000
while they change that state.

11:36.000 --> 11:39.000
So maybe this split isn't possible for your case.

11:39.000 --> 11:42.000
But sometimes this is a possible split.

11:42.000 --> 11:46.000
You can move the disabled components over here.

11:46.000 --> 11:49.000
And now, actually, if you move them over there,

11:49.000 --> 11:52.000
you can probably get rid of a lot of their data,

11:52.000 --> 11:54.000
because like a disabled component,

11:54.000 --> 11:58.000
which isn't in the UI, probably is never hovered or selected, right?

11:58.000 --> 12:02.000
So you can get rid of them in those cases.

12:02.000 --> 12:07.000
And that just means that when you move your component over from being disabled to becoming enabled,

12:07.000 --> 12:14.000
hoping data around, but I assume your components aren't constantly enabling and disabling.

12:14.000 --> 12:16.000
So maybe it makes sense.

12:16.000 --> 12:21.000
All right, and I've moved the components over to this component table,

12:21.000 --> 12:23.000
which is here.

12:23.000 --> 12:29.000
And it looks pretty much like the component looked,

12:29.000 --> 12:36.000
except now, every single thing here is kind of an array of some sort.

12:37.000 --> 12:42.000
So this is not an object that exists for each component.

12:42.000 --> 12:46.000
This exists for each hierarchy of components.

12:46.000 --> 12:51.000
Each array there holds data for all the components.

12:51.000 --> 12:56.000
So that type there, it is now a flexible index array.

12:56.000 --> 13:01.000
IE just a uint8 or uint16 or uint32 array.

13:01.000 --> 13:05.000
And it is as long as you have components.

13:06.000 --> 13:09.000
It's length is the number of components you have.

13:09.000 --> 13:12.000
And now your component has an index.

13:12.000 --> 13:14.000
I am component index 4.

13:14.000 --> 13:19.000
Okay, I will look into the type list or type array at index 4.

13:19.000 --> 13:23.000
And I will find there, what's a uint8 or uint16 or uint32 array.

13:23.000 --> 13:26.000
So I find another number there.

13:26.000 --> 13:33.000
That points to our data storage somewhere here, there, data parts.

13:33.000 --> 13:37.000
I have a list of unique strings, unique type strings.

13:37.000 --> 13:41.000
So all our components now, they don't actually know their type.

13:41.000 --> 13:43.000
They know their type index.

13:43.000 --> 13:46.000
And you can just go look up the actual type string here.

13:46.000 --> 13:49.000
And that list holds no extra data.

13:49.000 --> 13:54.000
It's a unique list of unique strings.

13:54.000 --> 13:59.000
Now, because probably your list of types is fairly small.

13:59.000 --> 14:02.000
Maybe it's like 200.

14:02.000 --> 14:06.000
You are only using one byte of data, or maybe two bytes of data,

14:06.000 --> 14:10.000
to store your type per component.

14:10.000 --> 14:13.000
All right.

14:13.000 --> 14:16.000
Harvard, I'm making an assumption.

14:16.000 --> 14:21.000
Maybe your system is such that you don't have like,

14:21.000 --> 14:24.000
hierarchical hovering type of thing.

14:24.000 --> 14:27.000
There is only ever one component that is hovered at a time.

14:27.000 --> 14:30.000
So why do we have that Boolean in every single component?

14:30.000 --> 14:32.000
We don't need it.

14:32.000 --> 14:35.000
We need one index, which component is currently hovered,

14:35.000 --> 14:37.000
or if none, the none.

14:37.000 --> 14:38.000
Okay.

14:38.000 --> 14:42.000
Save the bit of data there, or memory.

14:42.000 --> 14:44.000
Selected components.

14:44.000 --> 14:47.000
Again, why do we have that Boolean there?

14:47.000 --> 14:51.000
You probably don't have all of the components selected at the same time.

14:51.000 --> 14:53.000
It's probably changing.

14:53.000 --> 14:58.000
Maybe you have these three, these four components selected right now,

14:58.000 --> 15:01.000
and then some at a later time.

15:01.000 --> 15:05.000
So just put that in a set, or even better.

15:05.000 --> 15:08.000
If you can, if you don't mind it being a little slower,

15:08.000 --> 15:15.000
maybe to look up, make that an array that you just push and pop from.

15:15.000 --> 15:18.000
Get to your little bit better,

15:18.000 --> 15:21.000
otherwise, but it's negligible most.

15:21.000 --> 15:23.000
All right.

15:23.000 --> 15:24.000
Parent.

15:24.000 --> 15:27.000
Now, this is just what we had before.

15:27.000 --> 15:31.000
So we have an index list.

15:31.000 --> 15:35.000
And now, this is the flexible index array again.

15:35.000 --> 15:36.000
How many components?

15:36.000 --> 15:39.000
This is pointing back into the component table.

15:39.000 --> 15:41.000
How many components have?

15:41.000 --> 15:43.000
You have that is the length of this array,

15:43.000 --> 15:47.000
and each item here is an index into the component.

15:47.000 --> 15:50.000
It's into the component itself, component table itself.

15:50.000 --> 15:54.000
And if this component doesn't have a parent,

15:54.000 --> 15:59.000
then we instead use the maximum value for that array.

15:59.000 --> 16:02.000
So in a unit eight array, it would be 255.

16:02.000 --> 16:06.000
If you see that this is pointing to an index 255,

16:06.000 --> 16:09.000
then you know, okay, that just means that there is no parent.

16:09.000 --> 16:13.000
Note that that does mean that if your array length,

16:13.000 --> 16:16.000
if your number of components is 255,

16:16.000 --> 16:19.000
you actually need to use a unit 16 array,

16:19.000 --> 16:23.000
because otherwise it would get like it wouldn't work.

16:23.000 --> 16:24.000
Okay.

16:24.000 --> 16:28.000
Children, again, I've made an assumption here.

16:28.000 --> 16:31.000
This is where context knowledge would come in.

16:31.000 --> 16:34.000
You know what kind of components are common in your system.

16:34.000 --> 16:37.000
I've made the assumption that in this system,

16:37.000 --> 16:42.000
it's actually uncommon that there are children.

16:42.000 --> 16:46.000
Maybe this is like a very wide kind of system,

16:46.000 --> 16:49.000
where your root component has a lot of children,

16:49.000 --> 16:52.000
and those may be sometimes have children,

16:52.000 --> 16:58.000
but mostly it's just like one very, very wide children list.

16:58.000 --> 17:03.000
So in that case, it doesn't make sense to have a list of components,

17:03.000 --> 17:05.000
or an array of components,

17:05.000 --> 17:09.000
component indexes for each component that you have.

17:10.000 --> 17:12.000
It may be makes sense to have a hash map,

17:12.000 --> 17:13.000
where you can look up,

17:13.000 --> 17:15.000
hey, my index is four,

17:15.000 --> 17:17.000
do I have children,

17:17.000 --> 17:19.000
and the hash maps is no you don't.

17:19.000 --> 17:21.000
Okay.

17:21.000 --> 17:23.000
If instead,

17:23.000 --> 17:27.000
it's common that your components do have a small amount of components,

17:27.000 --> 17:29.000
or children, sorry.

17:29.000 --> 17:33.000
Then it would make sense to actually turn this into two types of arrays,

17:33.000 --> 17:35.000
one for the number of components,

17:36.000 --> 17:38.000
a number of children you have,

17:38.000 --> 17:45.000
and another that points into a type array of component indexes.

17:45.000 --> 17:47.000
And that with that,

17:47.000 --> 17:49.000
you would get,

17:49.000 --> 17:52.000
well, the number of children then,

17:52.000 --> 17:55.000
basically becomes usually a unit eight,

17:55.000 --> 17:57.000
so you're using one by for that,

17:57.000 --> 18:02.000
and then you point to this type array list of children indexes.

18:02.000 --> 18:03.000
You point to the beginning,

18:03.000 --> 18:06.000
and your length determines how many items you have there.

18:06.000 --> 18:09.000
It becomes a bit more complicated,

18:09.000 --> 18:11.000
and that then requires that you need to do it

18:11.000 --> 18:13.000
or own garbage collection with that,

18:13.000 --> 18:15.000
so you have fun.

18:15.000 --> 18:20.000
But it does give you the optimal memory usage.

18:20.000 --> 18:23.000
It becomes a basically succent data structure,

18:23.000 --> 18:27.000
where it uses only the amount of memory that you absolutely need.

18:27.000 --> 18:31.000
The width and height values that we saw before,

18:32.000 --> 18:35.000
those were string or number.

18:35.000 --> 18:39.000
I'm guessing this is probably a pixel based system,

18:39.000 --> 18:43.000
but there is an optional possibility

18:43.000 --> 18:46.000
that you can give like 100%

18:46.000 --> 18:49.000
or some calc value,

18:49.000 --> 18:50.000
like basically,

18:50.000 --> 18:52.000
yeah, you're usually using pixels,

18:52.000 --> 18:54.000
but if you want to do CSS,

18:54.000 --> 18:55.000
you can.

18:55.000 --> 18:58.000
But usually you use pixels, right?

18:58.000 --> 19:01.000
And usually you use pixels that are less than 10,000,

19:01.000 --> 19:04.000
because your screen isn't very wide.

19:04.000 --> 19:08.000
So we can just store the width in,

19:08.000 --> 19:12.000
and height in you in 16 arrays by default.

19:12.000 --> 19:17.000
And if you need the more advanced CSS features,

19:17.000 --> 19:20.000
we will store the maximum value,

19:20.000 --> 19:25.000
essentially we assign minus 1 to these arrays for your index.

19:26.000 --> 19:29.000
And then we have these hash maps on the site,

19:29.000 --> 19:31.000
where we then store the rest of your data.

19:31.000 --> 19:33.000
Like if you have,

19:33.000 --> 19:37.000
for some reason your width is 3 million pixels.

19:37.000 --> 19:38.000
Okay, sure,

19:38.000 --> 19:40.000
we will put it in the hash map for you.

19:40.000 --> 19:43.000
Or if your width is calc,

19:43.000 --> 19:45.000
100 minus 20 pixels,

19:45.000 --> 19:46.000
okay,

19:46.000 --> 19:48.000
we can store it there.

19:48.000 --> 19:51.000
But we don't want to be keeping,

19:51.000 --> 19:52.000
or this basically,

19:52.000 --> 19:57.000
it saves us 2 or 8 by 2 or 6 bytes on every single,

19:59.000 --> 20:06.000
every single component for their width height values on average.

20:09.000 --> 20:13.000
Then the scope name that I had there before.

20:13.000 --> 20:16.000
This is something I really like.

20:16.000 --> 20:19.000
So the scope name was 2 part string.

20:20.000 --> 20:23.000
First part is the hierarchical path.

20:23.000 --> 20:25.000
Essentially you can think like file path, for instance.

20:25.000 --> 20:28.000
Path to a folder where this component is defined in.

20:28.000 --> 20:30.000
And then the name part,

20:30.000 --> 20:34.000
which is a unique string within that folder.

20:37.000 --> 20:39.000
I'm going to make a guess here.

20:39.000 --> 20:41.000
Or actually this is based on our system,

20:41.000 --> 20:44.000
but let's say I'm making guess.

20:45.000 --> 20:48.000
The names in a particular,

20:48.000 --> 20:52.000
in a particular container,

20:52.000 --> 20:53.000
a particular path,

20:53.000 --> 20:55.000
a particular folder,

20:55.000 --> 20:58.000
are all to generate it.

20:58.000 --> 21:00.000
Nobody usually,

21:00.000 --> 21:02.000
like you can change the file,

21:02.000 --> 21:04.000
file name, or the name part,

21:04.000 --> 21:06.000
but most people don't.

21:06.000 --> 21:08.000
You just create like 1000 components,

21:08.000 --> 21:09.000
save,

21:09.000 --> 21:12.000
and they are component 1 component 2 component 3.

21:12.000 --> 21:14.000
So, so on and so forth.

21:16.000 --> 21:20.000
Now, within if you take the path and the name together

21:20.000 --> 21:22.000
and take it into a string,

21:22.000 --> 21:26.000
you will never ever find any duplicates anywhere.

21:26.000 --> 21:28.000
It is a completely unique identifier.

21:28.000 --> 21:30.000
But if you split them apart,

21:30.000 --> 21:32.000
path and name,

21:32.000 --> 21:34.000
and the name is also generated,

21:34.000 --> 21:35.000
usually not changed.

21:35.000 --> 21:39.000
Path is a folder where you have 1000 components.

21:39.000 --> 21:43.000
These two things repeat all over the system.

21:43.000 --> 21:45.000
Everywhere, everybody has like,

21:45.000 --> 21:48.000
you have everybody in the same folder

21:48.000 --> 21:50.000
and then unique names

21:50.000 --> 21:54.000
that are repeated in the next folder over.

21:54.000 --> 21:58.000
So, we can just put those unique names

21:58.000 --> 22:00.000
and unique scopes or paths,

22:00.000 --> 22:05.000
folders into different string arrays here.

22:05.000 --> 22:09.000
And then again, we refer to those with a flexible index array.

22:09.000 --> 22:10.000
IE,

22:10.000 --> 22:13.000
if my unique name, name 1,

22:13.000 --> 22:14.000
or component 1,

22:14.000 --> 22:18.000
is the first unique string that we have.

22:18.000 --> 22:19.000
Name string that we have,

22:19.000 --> 22:22.000
then this will hold the index 0,

22:22.000 --> 22:24.000
and I can just find my name here,

22:24.000 --> 22:26.000
in the index 0,

22:26.000 --> 22:28.000
and I get component 1 from there.

22:28.000 --> 22:30.000
I do the same for my scope.

22:30.000 --> 22:31.000
I combine them,

22:31.000 --> 22:34.000
and that's my actual unique identifier.

22:34.000 --> 22:36.000
Now, why would you do this?

22:36.000 --> 22:38.000
Well, you say memory,

22:38.000 --> 22:40.000
the browser will not,

22:40.000 --> 22:44.000
or your engine will not actually remove

22:44.000 --> 22:48.000
duplicate strings very aggressively,

22:48.000 --> 22:51.000
but you can do it yourself this way.

22:51.000 --> 22:53.000
And now,

22:53.000 --> 22:57.000
if you need to compare two unique identifiers,

22:57.000 --> 22:59.000
normally it would be a string comparison.

22:59.000 --> 23:02.000
Now, it's a comparison of two numbers,

23:03.000 --> 23:06.000
or four numbers, two pairs of numbers,

23:06.000 --> 23:08.000
between each other.

23:08.000 --> 23:10.000
If both values match,

23:10.000 --> 23:12.000
then this is the same unique identifier.

23:12.000 --> 23:14.000
Otherwise, it's not.

23:14.000 --> 23:15.000
All right.

23:15.000 --> 23:17.000
So, that's pretty cool,

23:17.000 --> 23:18.000
I think,

23:18.000 --> 23:19.000
I think anyway,

23:19.000 --> 23:20.000
yeah.

23:20.000 --> 23:22.000
Where is my...

23:24.000 --> 23:27.000
Yes, good, good, good.

23:27.000 --> 23:31.000
Don't worry about the weirdness here.

23:31.000 --> 23:34.000
So, in conclusion,

23:34.000 --> 23:35.000
remember,

23:35.000 --> 23:38.000
losing weight is about approaching the ideal memory weight,

23:38.000 --> 23:40.000
without ballooning the rest.

23:40.000 --> 23:42.000
Don't go whole wild.

23:42.000 --> 23:44.000
Don't do this for every single thing you have.

23:44.000 --> 23:47.000
If you have like 10 components,

23:47.000 --> 23:49.000
not worth it.

23:49.000 --> 23:51.000
But if you have 100,

23:51.000 --> 23:53.000
if you have 10,000,

23:53.000 --> 23:56.000
then starts making sense.

23:56.000 --> 23:58.000
Let's see if I have...

23:58.000 --> 23:59.000
Yeah.

24:02.000 --> 24:03.000
Okay.

24:03.000 --> 24:04.000
Yeah.

24:04.000 --> 24:06.000
Maybe it comes up later.

24:06.000 --> 24:07.000
But, yeah,

24:07.000 --> 24:08.000
using structure of arrays,

24:08.000 --> 24:10.000
enables you to use the tools

24:10.000 --> 24:12.000
that JavaScript has for optimizing memory,

24:12.000 --> 24:13.000
for using,

24:13.000 --> 24:15.000
or kind of,

24:15.000 --> 24:18.000
using the actual ideal memory weight.

24:18.000 --> 24:21.000
Yeah, here is that some really examples.

24:21.000 --> 24:22.000
So, I,

24:22.000 --> 24:24.000
at a costumers place,

24:24.000 --> 24:29.000
I saw 80 megabytes being used in a single thing.

24:29.000 --> 24:30.000
And that was horrible,

24:30.000 --> 24:32.000
and I took it through this filter,

24:32.000 --> 24:35.000
and got out nine megabytes out of it.

24:35.000 --> 24:38.000
And then I generated some very repetitive test data,

24:38.000 --> 24:41.000
which ballooned the original structure,

24:41.000 --> 24:44.000
sized to 350 megabytes,

24:44.000 --> 24:46.000
15 megabytes after optimization.

24:46.000 --> 24:48.000
Okay, that was heavily repetitive,

24:48.000 --> 24:51.000
so it makes sense that it optimizes the weight better,

24:51.000 --> 24:52.000
compresses the weight better,

24:52.000 --> 24:53.000
but still.

24:53.000 --> 24:56.000
And then a different example

24:56.000 --> 24:57.000
where I did this,

24:57.000 --> 25:00.000
I got from 10 megabytes to 3 megabytes,

25:00.000 --> 25:03.000
or 2, 3 megabytes with the same stuff.

25:03.000 --> 25:04.000
Okay.

25:04.000 --> 25:07.000
But you're probably thinking about this.

25:07.000 --> 25:10.000
I showed you that type arrays are horrible.

25:10.000 --> 25:14.000
Like 100 bytes for a type array,

25:14.000 --> 25:18.000
and an array buffer in no Chrome and 200 in node,

25:18.000 --> 25:19.000
like,

25:19.000 --> 25:20.000
isn't that horrible?

25:20.000 --> 25:24.000
Like, why would I use a type array if it's so big?

25:25.000 --> 25:28.000
And obviously the point is that the item sizes,

25:28.000 --> 25:29.000
then small, but yes,

25:29.000 --> 25:32.000
this is a real kind of fundamental problem with,

25:32.000 --> 25:34.000
not like object oriented programming per se,

25:34.000 --> 25:36.000
but structural inheritance.

25:36.000 --> 25:38.000
Structural inheritance basically says,

25:38.000 --> 25:40.000
when you inherit a class,

25:40.000 --> 25:42.000
and you become more focused,

25:42.000 --> 25:43.000
you have better focus.

25:43.000 --> 25:45.000
This is better use.

25:45.000 --> 25:47.000
It only ever grows,

25:47.000 --> 25:50.000
which is kind of the wrong way around you would think.

25:51.000 --> 25:54.000
But yeah, array buffer still makes sense.

25:54.000 --> 25:56.000
They break even at 20 or 50,

25:56.000 --> 25:58.000
depending on kind of your use case.

25:58.000 --> 26:02.000
But the engine could still lose weight.

26:02.000 --> 26:04.000
And if it did,

26:04.000 --> 26:07.000
it would be a Nova JavaScript engine.

26:07.000 --> 26:13.000
Basically what we do is use these kinds of tricks

26:13.000 --> 26:17.000
to approach ideal memory weight,

26:18.000 --> 26:20.000
but become a bit more complex,

26:20.000 --> 26:23.000
and have more code, way more code.

26:23.000 --> 26:25.000
So our sub-class objects,

26:25.000 --> 26:28.000
IE, when we do an un8 array or type,

26:28.000 --> 26:30.000
any type array or array buffer,

26:30.000 --> 26:32.000
they no longer grow in size.

26:32.000 --> 26:33.000
They actually shrink in size,

26:33.000 --> 26:35.000
because they drop out all the objects stuff,

26:35.000 --> 26:37.000
and we have a hash map on the side.

26:37.000 --> 26:40.000
Like, if you really want to use that un8 array,

26:40.000 --> 26:42.000
or that array buffer as an object,

26:42.000 --> 26:43.000
we will make it possible,

26:43.000 --> 26:45.000
but it's not going to be cheap.

26:46.000 --> 26:48.000
And like,

26:48.000 --> 26:51.000
we actually have our current array buffer,

26:51.000 --> 26:52.000
is 32 bytes,

26:52.000 --> 26:54.000
and our type array is 20 bytes,

26:54.000 --> 26:59.000
and I can push them down to 12 or 16 bytes each.

26:59.000 --> 27:03.000
So, I have more examples.

27:03.000 --> 27:07.000
I have more slides that cover these in kind of more detail,

27:07.000 --> 27:11.000
but I'm going to leave those for you to discover.

27:11.000 --> 27:13.000
There's the GitHub link for the code.

27:13.000 --> 27:15.000
There are more code examples,

27:15.000 --> 27:18.000
the real code that I have done at work,

27:18.000 --> 27:20.000
which I didn't have time for,

27:20.000 --> 27:22.000
and then links for no large JavaScript engine.

27:22.000 --> 27:25.000
You can read my blog posts on some of this stuff,

27:25.000 --> 27:27.000
and so on.

27:27.000 --> 27:29.000
Questions?

27:29.000 --> 27:31.000
Thank you.

27:31.000 --> 27:34.000
Thank you.

27:34.000 --> 27:36.000
Cool.

27:36.000 --> 27:39.000
Is there a getting started page?

27:40.000 --> 27:44.000
No, not at the moment.

27:44.000 --> 27:48.000
There's a fairly large amount of contributing information

27:48.000 --> 27:50.000
for the engine.

27:50.000 --> 27:52.000
The engine is still very rough.

27:52.000 --> 27:56.000
We pass only a bit more than 50% of the test 2,

27:56.000 --> 27:59.000
2, 6, 2, test 3, sweet.

27:59.000 --> 28:02.000
So, it's not like, don't take this into production,

28:02.000 --> 28:06.000
but if you want to program in Rust and work on a JavaScript engine,

28:06.000 --> 28:09.000
you can see how the sausages make so to say.

28:09.000 --> 28:11.000
We are there for you.

28:11.000 --> 28:12.000
Yeah.

28:12.000 --> 28:16.000
So, it seems to take away a lot of the dynamicness of the transcripts.

28:16.000 --> 28:20.000
And if you look at that, you can also think you're very,

28:20.000 --> 28:23.000
actually, you are reading it immediately.

28:23.000 --> 28:25.000
So, why don't you send the script,

28:25.000 --> 28:28.000
which is that it's a little hard to send in

28:28.000 --> 28:31.000
that those orders for you, which is not the easy task.

28:31.000 --> 28:33.000
That would probably be a bit,

28:33.000 --> 28:36.000
but the question was, why not use assembly script,

28:36.000 --> 28:39.000
and then turn into resin and, like,

28:39.000 --> 28:42.000
have an actual proper engine do it for you?

28:42.000 --> 28:45.000
That would probably be the smarter idea, yes.

28:45.000 --> 28:48.000
Okay, thank you.

