I’m optimizing allocations away, for printing general strings (one of the last one is because of Libc.malloc(200), effectively in Julia, and it could be on the stack if Julia had such capability like in C).
It IS dangerous to get a pointer to the stack in general (if the stack-frame goes away), so I think this is simply not possible in Julia for good reasons, but is there a workaround? One would be translating some functions in Julia Base to C.
@mkitti, I’m now looking also into:
GitHub - mkitti/StaticStrings.jl: Fixed-length strings in Julia represented by NTuples (InlineStrings.jl is another option).
julia> cs = cstatic"Hello world!\n"
cstatic"Hello world!\n"13
julia> @time ccall(:printf, Cint, (Ptr{Cchar},), cs);
Hello world!
0.000037 seconds (2 allocations: 48 bytes)
Still two, but curiously way worse (also much worse than just with Julia's default String):
julia> @time print(cs);
Hello world!
0.000237 seconds (28 allocations: 752 bytes)
julia> @time ccall(:printf, Cint, (Ptr{CStaticString{13}},), Ref(cs));
Hello world!
0.000043 seconds (2 allocations: 48 bytes)
julia> @time Ref(cs);
0.000015 seconds (1 allocation: 32 bytes)
@edit Base.RefValue{CStaticString{13}}(cs) # see first with @edit Ref(cs); I believe I tracked down to there:
mutable struct RefValue{T} <: Ref{T}
x::T
RefValue{T}() where {T} = new()
RefValue{T}(x) where {T} = new(x)
end
I believe I tracked down to Julia constructing that RefValue, that latter new, because the string is on the stack and it needs a mutable struct, i.e. on the heap to point to.
Where is the other allocation coming from? I think it must be from :printf
, and where is that exactly, in Libc? I haven’t tracked down yet, at least missed in it Julia if defined there.
With StaticCompiler.jl, if I recall, you have C-strings without allocations, but then you use Libc directly (maybe a good thing), and threads (nor libUV called) are not supported (a bad thing), also I don’t want the strings to be on the heap, or unidiomatic code (using Libc.malloc directly or indirectly).