#charts!

1 messages ยท Page 1 of 1 (latest)

drowsy parcel
#

just in case ayone else wants to see the charts too (log scale Y axis). there's more off the high end but ti's pretty boring beyond that

#

notably, there does seem to be a "second peak" around 50s but it is very weak. 3 is also a bit of a weak showing relative to other low numbers, which i dont' have a particularly satisfying expanatin for yet

#

the 3 anomaly is much more prominent on a linear scale

#

oh, hmm

#

i wonder if ti's actualyl a 2 anomaly ๐Ÿค”

valid timber
#

Yea the 3 is pretty odd

drowsy parcel
#

a peak aroudn 4, but 0 and 1 clamped to 2

#

that would make the shape make sense

#

i guess 0 wouln't happen, but 1 is feasible

valid timber
#

Huh, that would make sense. Since this is using the phobos compiler I could remove the max stack limitation, but I don't think I really need to since this makes a lot of sense

crystal zinc
#

how did you call the 2nd peak around 50. whats the intuition for that?

drowsy parcel
#

you mean when i had guessed and ballparked it there before any data? just having seen lots of locals-heavy main chunks

#

wild ass guess that got lucky

#

when you see lots of bytecode dumped funtions you see that count along with it and you just start to get a feel for it

valid timber
#

Here's the updated data with the 2 minimum stack limitation removed. Don't ask me how there's so many 0s ๐Ÿ˜‚

#

And we can already see that you're right

drowsy parcel
#

0 basically ahs to be function() end ๐Ÿค”

valid timber
#

yep

drowsy parcel
#

and yeah that unfolds nicely down there

#

3776 is a pretty small number among all the things, that could easily be a few doc files i'd think?

valid timber
#

Oh true! I forgot about those, they are included in several mods

drowsy parcel
#

that's about the only reason to have that many stubs

#

yeah taht makes a much more sensible shape at the bottom now

valid timber
#

(Oh you remade the graph with the different kind of input data, sorry!)

drowsy parcel
#

it's just google sheets

valid timber
#

I suppose with experience it's easy. I did install libre office and made a chart very quickly... but making it show what I want it to would take me time

drowsy parcel
#

the log scale / high end chart looks about the same of course

drowsy parcel
#

the first one was harder since you gave me the raw data first and i had to get the counts first then chart it

#

but pre-summarized it's easy :p

#

and "just chuck it in a histrogram to see what it looks like" is a very common strategy of mine trying to get a feel for unfamiliar data :p

#

i'm actually surprised how clean and straight the line is even after the second peak, i expected teh chaos to set in much sooner

#

but i guess that's what a big data set does

valid timber
#

nice! I was going to share a screenshot but decided that it's not useful info ๐Ÿ™ˆ

#

And for the record, 476 out of the 2490 files with empty functions in them contain .vscode in their path. That's about the best I got out of that

drowsy parcel
#

i'm actualyl more curious about the 1s now becuase all i can come up with is things of the form function() return "foo" end

#

the 0s are few enough that doc stubs seems to adequately explain them

#

but 1 is pretty hard to do ๐Ÿค”

valid timber
#

There's actually a lot of real files with zeros in them. I've not looked at much, but one of them had an empty on version changed function, so it's also templates it seems

drowsy parcel
#

hmm, i guess an upval table lookup by constant string would only use 1 so you could look up a global function and call it

#

i would count templates to be equivalent to doc stubs tbh

valid timber
#

fair enough

drowsy parcel
#

just a differnet kind of docs

#

oh hmm

#

empty event handlers would be a 1

#

since they'd be declared with 1 arg and use nothing in body

#

maybe templates are a different group :p

valid timber
#

That's true. I could add param count and local count to the output too... Or even random things like instruction count. Honestly not sure how to determine what the 1s are about...

drowsy parcel
#

it's hard to come up with something doing useful work in 1 ๐Ÿค”

#

max stack includes the params already doesn't it?

valid timber
#

yea

drowsy parcel
#

oh you mean separate them

valid timber
#

exactly

drowsy parcel
#

my bet is on them being empty(ish) functions with 1 declared arg

#

placeholders that never got filled

#

i can't come up with anything that would work in only 1 beyond returning an arg as-is, returning a literal, or calling a global function by name with no args

valid timber
#

my bet is on them being empty(ish) functions with 1 declared arg
placeholders that never got filled
To determine that I'll try to use the formatter to print out just those functions so I can actually look at them. shouldn't be too hard, but unfrotunately won't be a graph :P

drowsy parcel
#

and i'm not even sure if returning an arg as-is would actually do it in 1, it might still copy it

valid timber
#

the return instruction will use single return values in place if possible afaik

drowsy parcel
#

but i'm pretty sure that ```lua
function()
some_global()
end

valid timber
drowsy parcel
#

i think plain lua is a little less optimistic about it but i don't remember for sure off hand

crystal zinc
#

util has a bunch of 1 line functions like

function util.by_pixel(x,y)
  return {x / 32, y / 32}
end```

and cliff rotations use a couple  

could there be a lot of that elsewhere. hidding a lttile math formulas away in a 1 line function.
drowsy parcel
#

1 register, not 1 line

valid timber
drowsy parcel
#

yeah they didn't want to try to see if the whole set was in place in order, i recall being very excited about phobos being able to pull that trick :p

drowsy parcel
# drowsy parcel 1 register, not 1 line

counting registers is a much weirder measure, and 1 is an insane restriction - the lua compiler won't even bother attempting to compile a function with less than 2 normally, jan specifically modified one to get us the 0 and 1 counts for this

#

because even most basic operations involve at least 2 registers

#

and function params are reserved right off the top, so if you use the 1 register you get on that you can't use basically anything else

valid timber
#

Had to run afk for a bit there, but yea that's a good summary of registers.

drowsy parcel
crystal zinc
#

ah. so even
function(x) return (x+1)
is multiple registers?

drowsy parcel
#

yeah it can't reuse teh one x is in, so it has to allocate another temp for x+1 to go in

#

oh, but ```lua
function(x)
x=x+1
return x
end

shy python
#

primitives are also treated like pass by reference right? then it should fit with 1

valid timber
drowsy parcel
#

my main question is if the complicated semantics of = allow it to do it all in one, but i'm pretty sure since x is a local here it all works

#

i don't htink i invoked anything fancy on the = there with no tables and no commas, so it should behave...

#

but yeah the only other one-register operation i've come up with is table lookup from an upval table with a contant key, aka global variable lookup

#
function()
local x = global_x
x=x+1
global_x = x
return x
end

๐Ÿค”

valid timber
#

yea, = is smart (which is also why you've called it complicated, kind of related), but just to be sure I double checked

-- lua: function at @temp/test.lua:2-5
-- lua: 1 params | 0 upvals | 2 max stack
-- lua: 3 instructions | 1 constants | 0 functions
local function f(x)
--   3   0 lua:   2f     1  ADD       R(0|x) := R(0|x) + 1                                [a 0] [b 0] [c 256]
  x=x+1
--   4   0 lua:   2f     2  RETURN    return 1 results starting at R(0|x)                 [a 0] [b 2]
  return x
--   5   0 lua:   2f     3  RETURN    return 0 results starting at R(0|x)                 [a 0] [b 1]
end
valid timber
# drowsy parcel ```lua function() local x = global_x x=x+1 global_x = x return x end ``` ๐Ÿค”

Don't even have to! ๐Ÿช„

-- lua: function at @temp/test.lua:2-5
-- lua: 0 params | 1 upvals | 2 max stack
-- lua: 6 instructions | 2 constants | 0 functions
local function f()
--   3   0 lua:   2f     1  GETTABUP  R(0) := Up(0|_ENV)["x"]                             [a 0] [b 0] [c 256]
--   3   0 lua:   2f     2  ADD       R(0) := R(0) + 1                                    [a 0] [b 0] [c 257]
--   3   0 lua:   2f     3  SETTABUP  Up(0|_ENV)["x"] := R(0)                             [a 0] [b 256] [c 0]
  x=x+1
--   4   0 lua:   2f     4  GETTABUP  R(0) := Up(0|_ENV)["x"]                             [a 0] [b 0] [c 256]
--   4   0 lua:   2f     5  RETURN    return 1 results starting at R(0)                   [a 0] [b 2]
  return x
--   5   0 lua:   2f     6  RETURN    return 0 results starting at R(0)                   [a 0] [b 1]
end
drowsy parcel
#

naming it saves looking it back up the second time though

valid timber
#

This is true

drowsy parcel
#

and i wasn't sure = woudl behave with the upvals

#

good to see it does though

valid timber
#

Alright, so looking at the functions with 1 stack (which I can't legally share unfortunately) it seems like lots of them are simply interacting with globals. Even things like game.surfaces[1].foo = true.
Or function calls to functions that are in a global table, without arguments of course.
Or a constructor function, without paramters, that creates a record only table (no list) and returns that.
Yea looking through more and more, global variables is the answer. You can even have if statements.

drowsy parcel
#

oh huh, i guess it woudl reuse the temp for a deep access ๐Ÿค”

valid timber
#

yep

drowsy parcel
#

and it doesn't have to be globals, captured higher locals would also work

#

just that the most common one is _ENV