-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feature request: local static variables #15056
Comments
There's already an open issue about the fact that |
If you search for "static variables" in the github search you will find discussion about this. The conclusion was that variables like this should be stack allocated and there are open PRs that have started working towards this. |
Thanks, I see now that this issue has been mentioned in issues #5148 and #12627, I missed them while looking up for a possible solution. But making these variables both const and global introduces unnecessary global names and conflicts. Now, if it were possible for the user to somehow specify exactly that but without introducing extra global names... I understand that this would break current language semantic but since currently const has no effect in local scope, is it possible to to change the behaviour of const keyword within the functions so that it would be able to refer only to the variables/arrays that are true constants (e.g. literals, literal arrays, etc.) at the binding level within the scope? The local keyword for variables already does the job for the objects that can be modified, so there is some overlap in functionality. Or, maybe the compiler should be able to recognize the simplest cases of const literals and literal arrays (maybe multiplied by simple functions with literal arguments) and act accordingly? Constant literal arrays are constants after all, and performance gains for automatically moving them to the outside the scope are so big. I would agree that const should refer only to a binding, and the user should not expect the content of an array to be immutable in this context. |
You can use |
Closely related: #5024 |
In this situation, using let will completely hide the array - it will be Probably I should simply wait for proper implementation of static local On Fri, Feb 12, 2016 at 11:02 PM, Jeff Bezanson notifications@github.com
|
Someone posted a macro somewhere which I modified: macro static(init)
var = gensym()
eval(current_module(), :(const $var = $init))
var = esc(var)
quote
global $var
$var
end
end
function foo()
J = @static zeros(5,5)
end
julia> @allocated foo()
0
|
You can put the function definition inside the let block. I don't see why this doesn't work. |
Unfortunately, then the function is unavailable and I have an error.
if the function is defined as follow
|
On the other hand, Kristoffer's solution is working! Thanks so much. This is a very good macro, should definitely go into the mainline of Julia. Timings:
if the function defined as follows:
|
You are missing the
No, it is identical with declaring a global and has all the issues of that approach. |
Well, if it is a global unique name that is not interfering with other names, I am perfectly happy with it as a workaround. One just has to be sure that gensym() is generating truly unique names. I hope it does. Still, saying something like static const a = [1 2 3] would be much cleaner. |
Correct, adding global i0eva immediately after the function declaration fixed the error and the timings
Still, it is not as elegant solution, the code is somewhat harder to read On Sun, Feb 14, 2016 at 11:11 AM, Yichao Yu notifications@github.com
|
One more minor modification. Saying const p96to192 = @static [
0.3989422804013822E+00, 0.4986778509112728E-01,
0.2805061543528473E-01, 0.2922179806303123E-01,
0.4451046595352375E-01, 0.1022708740517523E+00] inside the code really does the job. So, the question is only if gensym() always generates unique names for the global scope. Should they be in a different namespace instead? |
You will get unique variable names. |
I could imagine a |
Will the |
I think that's unlikely; there are other ways to accomplish this so it doesn't seem so important. |
Could the/a "correct" solution for this be added to the FAQ? |
|
|
@yuyichao |
Sure but
|
@yuyichao My point is that |
I'm not sure what you are trying to argue about my comment here. If you just want to highlight the combination of The comment I was replying to is specifically about performance (and it does not mention the function of |
Doesn't macro static(expr)
QuoteNode(eval(__module__, expr))
end do the job here? (Except that it clashes with the existing |
It would be possible to use the same macro name by branching on the kind of expression. I.e. |
For the record,
Unfortunately it only works when called from the same module where it's defined. Otherwise, I get |
@dpinol, use macro static_var(init)
var = gensym()
Base.eval(__module__, :(const $var = $init))
quote
global $var
$var
end |> esc
end |
I have recently run into a major performance bottleneck while using const keyword for arrays inside functions. The following are two short examples that demonstrate this problem. In short, there is a huge performance penalty to declare even short const arrays inside the functions relative to global declarations (about a factor of 10 in this test, 0.000120 s for the slow version versus 0.000014 s for the fast version per 200 function calls) since the constant arrays are reinitialized every time the function is called, Moving constants into the outside (global) scope gets full Fortran-like speed. (In this example, I needed a faster version of the modified Bessel I_0 function for the so called Bessel-Kaiser window since the default AMOS based besseli is somewhat sluggish, 0.000130 s for the same workload).
Basically, a true equivalent of Fortran data or C const keyword is currently missing. The trick of moving constants outside the functions is imperfect for many obvious reasons, and a possible workaround using closures suffers from current inefficient implementation (plus it makes the code less readable). A possible solution would be to treat constants as initialized only once during the compilation step (just like the current treatment of global constants).
The code and the timings follow.
Slow version:
Slow version timings:
Fast version:
Fast version timings:
The text was updated successfully, but these errors were encountered: