Mutable struct assignment overloading / fast management of temporaries in expression

I’m creating a package which interfaces to a C library with C structs, and implements all the operator overloading for these structs. For example it looks a bit like

mutable struct MyStruct
  t::Ptr{CStruct}
  # Constructor/finalizer not shown for brevity
end

function f(x)
  return log(1+x)*1/sin(exp(x))
end

t = MyStruct()
a = f(t)

Currently, the operators are overloaded so that a new MyStruct is created for each operator output (e.g. for +(t1::MyStruct, t2::MyStruct), new memory is malloc-ed in C holding the return struct). I’ve implemented the finalizer for MyStruct so that the memory is freed when the resulting variable goes out of scope. This works, however it is slow because the memory for each struct is not compact for every temporary evaluated in the expression. For example, with log(1+x)*1/sin(exp(x)), the result 1+x creates a new MyStruct on the heap, then result log(1+x) makes another new MyStruct on the heap, etc). The C code includes a permanent array of preallocated structs I should be using for the temporaries in the expressions, to minimize cache misses in the evaluation of an expression. Preliminary testing with this shows a significant speedup.

The problem is that, I need to be able to distinguish between the temporaries stored in a preallocated buffer, and heap allocated memory which follows the Julia garbage collection/is stored in local variables. Currently there is a C++ interface of this C package, where the operators are overloaded so that they all return a separate temporary type. Then the assignment operator = is overloaded in the C++ so that at the end of the expression evaluation, the temporary type is copied to a heap allocated struct.

Unfortunately though, unlike C++, Julia does not allow me to overload assignment. I could use a macro for the assignment to do this conversion at the end, however that looks messy and defeats the purpose of taking advantage of type-stable generic expressions in Julia

I guess you don’t know about MutableArithmetics.jl? You probably want to implement certain MA methods for MyStruct, and then use MA for efficient operations on MyStruct.

Wow, I didn’t know about this, but at first glance I think it’s exactly what I’m looking for. Thanks!

1 Like