From what I’ve read and observed, it seems like there isn’t a way of eval-ing code in local scope or otherwise without incurring significant performance penalty (lots of extra memory allocations and significantly longer run time). However, this seems like a solution for our particular use-case.
# Top-level scope here
for _ in 1:1
data = Dict()
while receive_request_from_aws_sqs())
code = get_code_from_sqs()
include_string(Main, code) # code defines a function exec_code
function exec()
for iter in 1:4
@time begin
exec_code(data)
end
end
end
exec()
end
end
Is this reasonable? Is there some part of this that looks unnecessary?
We’re using @time
because @btime
executes in global state so we can’t evaluate how much time it takes to operate multiple instances of code coming in from SQS. So, we’re using @time
in a function based on our recommendation of Performance Tips · The Julia Language. Is that the best way of doing this.
Any input would be greatly appreciated.
1 Like
No, that is not feasible. But you can write a function that returns a function. Which is probably what you want to do.
Hi @pdeffebach,
Thanks for your reply but we really do need to evaluate arbitrary code that can share state stored in a dictionary. We have a serverless function that generates cache-optimized Julia code.
Also, if I may ask, why exactly is this infeasible? Where would I run in to issues performance or otherwise? Isn’t everything here in local scope since the whole thing is wrapped in a for
(should it be let
?) and include_string
is generating a function with locally scoped variables and this function is then being called from exec
? Where would we run into issues with this?
I don’t have the expertise to explain exactly why this is infeasible. But it has to do with world age issues from modifying the global state method table inside a local scope. Hopefully someone more informed than I an can explain it more clearly.
Well, it is working in this case. But I’m not entirely sure why.
In the code, I note that the for loop is in top-level scope. So the include_string
is able to create a function that can then be subsequently called. But the dictionary passed in is presumably in some sort of local scope. Or perhaps I am mistaken about that and maybe the dictionary is actually a global variable. Is there any disadvantage of that?
The Dict
will store arbitrary values anyway (it’s effectively a Dict{Symbol, Any}
so Julia wouldn’t be able to optimize usage of it necessarily. The function exec_code
does create local variables produced by calling functions on Dict
entries. Could this lead to a slowdown (for now, I’m just generating code that operates on data created in local variables but in the future I may be getting that data from the data
dictionary)?
Aside from the details about scope
and how include
works, if you can write a function which spits out valid Julia code, you can also write a function that returns a closure, right? Surely the second option must be easier.
1 Like