me1150
2020-3-7 14:38:18

Does anyone have experience with using large structs in Racket? I tried a simple experiment, declaring a (struct foo (foo-1 foo-2 ... foo-n)) and just running raco make , and it seems like the compilation phase is superlinear in the number of field structs:


me1150
2020-3-7 14:38:44

me1150
2020-3-7 14:39:46

Would this be considered a performance bug (and perhaps be fixed), or should I consider workarounds? (This is for auto-generated code, which is why I have such large structs)


soegaard2
2020-3-7 15:44:57

It looks worse than O(n*log(n)) so it’s okay to make an issue.

Which version of Racket was it? And was it plain Racket or the CS version? Do you have a link to the benchmark code?

Anyways - a hash table may be a better fit for the use case.


me1150
2020-3-7 15:48:49

Not CS; reproduced on Racket 7.3 on macOS and 7.4 on Debian


soegaard2
2020-3-7 15:51:03

Although not that old, it’s worth trying the latest versions. Due to the transition to Chez Scheme as back end, it is possible that the structure compilation was revised.

See: https://download.racket-lang.org/


mflatt
2020-3-7 15:56:29

@me1150 Do you need all of the individual field accessor/mutator bindings? If not, using make-struct-type directly may be a better option, since it gives you a position-based field selector and accessor.


me1150
2020-3-7 15:57:19

Yes, I do need accessors. Though that should still be O(n)?


mflatt
2020-3-7 16:07:31

Binding is not always liner, but the constant is much much smaller than shown in your graph. The problem doesn’t seem to be in struct itself, though.


mflatt
2020-3-7 16:15:35

It turns out that all of the time is in setting up struct-field-index, which can easily be better.


me1150
2020-3-7 16:18:29

Oh interesting! Thanks for taking the time to investigate. No worries if it’s not a high-priority issue to fix; I suspect not too much real Racket code uses gigantic structs. (I will switch to a different representation, maybe a vector with accessors I synthesize myself.) Let me know if you think I should open a GitHub issue for this.

Also, for a little bit of context, I actually encountered this while writing Rosette code, and then I went back and checked to see if the issue was in Racket or in Rosette. Turns out that both have this superlinear behavior, but Rosette seems to have a worse constant: https://github.com/emina/rosette/issues/147


moroze
2020-3-7 16:27:36

@moroze has joined the channel


mflatt
2020-3-7 16:27:47

I’ll push a repair that works for 10000 fields in under 1 second on my machine. That at least removes the struct-field-index setup from being a problem.


krismicinski
2020-3-7 17:58:56

I have never heard of this before, thanks for the pointer.


me1150
2020-3-7 18:43:19

Wow, thank you for the quick fix!


sorawee
2020-3-8 01:35:06

Thank you! I applied the fix to Rosette at https://github.com/emina/rosette/pull/148.


sorawee
2020-3-8 05:11:03

@mflatt is this due to how it’s very expensive to expand syntax-case with a lot of cases?