Skip to content

Commit 181f962

Browse files
committed
fix: avoid use of @generated for caching strings
1 parent 7b22a97 commit 181f962

File tree

1 file changed

+22
-20
lines changed

1 file changed

+22
-20
lines changed

src/Strings.jl

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -29,28 +29,30 @@ function dispatch_op_name(::Val{deg}, operators::AbstractOperatorEnum, idx) wher
2929
end
3030
end
3131

32-
@generated function get_op_name(op::F)::Vector{Char} where {F}
33-
try
34-
# Bit faster to just cache the name of the operator:
35-
op_s = if F <: Broadcast.BroadcastFunction
36-
string(F.parameters[1].instance) * '.'
37-
else
38-
string(F.instance)
39-
end
40-
if length(op_s) == 2 && op_s[1] in ('+', '-', '*', '/', '^') && op_s[2] == '.'
41-
op_s = '.' * op_s[1]
32+
OP_NAME_CACHE = (; x=Dict{UInt64,Vector{Char}}(), lock=Threads.SpinLock())
33+
34+
function get_op_name(op)
35+
h = hash(op)
36+
@lock OP_NAME_CACHE.lock let
37+
cache = OP_NAME_CACHE.x
38+
if haskey(cache, h)
39+
return cache[h]
4240
end
43-
out = collect(get(OP_NAMES, op_s, op_s))
44-
return :($out)
45-
catch
46-
end
47-
return quote
48-
op_s = typeof(op) <: Broadcast.BroadcastFunction ? string(op.f) * '.' : string(op)
49-
if length(op_s) == 2 && op_s[1] in ('+', '-', '*', '/', '^') && op_s[2] == '.'
50-
op_s = '.' * op_s[1]
41+
op_s = sizehint!(Char[], 10)
42+
if op isa Broadcast.BroadcastFunction
43+
append!(op_s, string(op.f))
44+
if length(op_s) == 1 && first(op_s) in ('+', '-', '*', '/', '^')
45+
# Like `.+`
46+
pushfirst!(op_s, '.')
47+
else
48+
# Like `cos.`
49+
push!(op_s, '.')
50+
end
51+
else
52+
append!(op_s, string(op))
5153
end
52-
out = collect(get(OP_NAMES, op_s, op_s))
53-
return out
54+
cache[h] = op_s
55+
return op_s
5456
end
5557
end
5658

0 commit comments

Comments
 (0)