rdb / nim-panda3d

Proof of concept nim binding for Panda3D
https://www.panda3d.org/
8 stars 5 forks source link

Reduce compile time #3

Open beef331 opened 1 year ago

beef331 commented 1 year ago

A common complaint I've seen in the Nim realtime chat is that the compile time for this project is long. I'll document some methods of reducing it.

1) Repeat Dollar operator definitions, presently each $ has it's own procedure and body, which means regardless if it's used or not it's semantically checked.

func `$`*(this: Thread): string {.inline.} =
  var str : StringStream
  this.output(str)
  str.data

func `$`*(this: MutexDirect): string {.inline.} =
  var str : StringStream
  this.output(str)
  str.data

...

Instead of the above one can do the following, which only causes a single semantic check, unless instantiation is made

type SimpleStringTypes = Thread or MutexDirect or ConditionVarDirect or ...
func `$`*(this: SimpleStringTypes): string {.inline.} =
  var str : StringStream
  this.output(str)
  str.data

2) Dont make swizzle procedures for every variation. This adds a ton of code which requires a ton of semantic checking, instead of making a procedure for each, we can just use an experimental dotOperator . For reference

rdb commented 1 year ago

Thank you, appreciated. I'll experiment with this. The bindings are auto-generated at the moment but I can write in some special cases for repeated code like this.

I have done some work locally on implementing dotOperators. I wasn't super excited about them as they're still experimental and I seem to recall some annoying behaviour regarding error cases and such, but I will benchmark their impact on compilation time.

rdb commented 1 year ago

I'm getting no measurable speed increase even from just deleting the swizzles from core.nim. It really doesn't seem that we can expect to get gains here. Given all the downsides of dot operators (experimental feature, awful diagnostics, more non-generated code) I am leaning towards leaving them as-is.

rdb commented 1 year ago

I've pushed some changes collapsing some duplicate generated methods as suggested.

If nim's semantic checking is so slow, maybe we can use macros to generate the AST for the wrapper functions at compile time? And ditto for the swizzles? Do you think this might be worth a try?

beef331 commented 1 year ago

I do not think using a macro will help much since the same amount of work is done by the compiler minus parsing. Though I could be wrong.

beef331 commented 1 year ago

Unrelated to compilation speed, but are your type's opaque pointers? If so you may want to do type MyType {....} = ptr object.

rdb commented 1 year ago

It depends. Some types are by-value types, a few are pointers, but most are smart reference counting pointers, that contain a special wrapper object similar to C++'s shared_ptr.

rdb commented 1 year ago

I used perf and discovered why it's so slow on ARM: implicit conversion functions. Once I turn them into regular procs it was super fast.

janEntikan commented 1 year ago

implicit.txt Here's the diff just in case it gets lost.

janEntikan commented 1 year ago

Just wanted to repeat the fact that I'm very happy with the resulting compile speeds!

rdb commented 1 year ago

Work is now continuing on the no-converters branch. Since the converters do provide some useful advantages that I want to keep (such as being able to assign nil to a Panda smart-pointer type) I haven't merged to main yet until I figure out if there's a way to get those advantages without the performance problems with converters.