It's important to realize that Julia's global variables are slow because
they are generally not a good design decision, not the other way around.
They could be optimized, but it's preferable to encourage taking a
different approach. Julia makes other similar tradeoffs, including
prohibiting eval() from interacting with the local scope. It's not that
this couldn't be implemented, it's just that there are much better ways of
expressing the problem that don't require this feature.

You've mentioned reasons that you use global variables, so I'll mention a
few reasons that I generally try to avoid them.

In short, if I use globals heavily, I find my code becomes unmaintainable
immediately after writing it, and therefore the program rapidly becomes
awful, bug-ridden, and impossible to add features to.

Having globals simultaneously increases the code complexity and decreases
readability. This is actually true of mutation in general, but mutation
becomes more difficult to track when the variables that are changing are
global. With local variables, you can see the explicit patterns of
data-flow. With global variables, you cannot safely assume that the
variable will not change during the execution of that function. Even if it
is true now, someone (or even you) might later want to add some cool
feature, but since they can't trace where that variable gets used, it
becomes incredibly difficult to ensure that the change won't impact other
parts of the code unintentionally.

A second part of avoiding globals is that it makes writing good tests much
harder. Ideally, a function does exactly one thing: it computes a result.
In some cases, that computation is to store a value somewhere. When a
function tries to do multiple things, it bugs become harder to trace, since
you can't separately test the cause and the effect.

Of course, I don't actually avoid them. Types, functions, STDIO, memory
allocation/gc are all global because the tradeoff is not worthwhile. I'm
also going to make a distinction between constants and mutatable globals.
It's perfectly reasonable to have constant data accessible from the global
scope.

Note: some people avoid passing variables around because they assume this
is a lot of work for the computer. It isn't. Like humans, it's a lot easier
for the compiler to track dependencies between local variables and function
parameters than to analyze a global variable.

oh, and I see John beat me to finishing this reply, but I will second his
recommendation of the c2.com wiki.


On Mon Dec 15 2014 at 4:40:53 PM Greg Plowman <[email protected]>
wrote:

> Hi,
>
> I understand using global variables can lead to poor performance.
> This is because types cannot be guaranteed? Globals could be reassigned
> with different types?
>
> For my purpose, I set up a lot of parameters as global variables.
> Then define lots of functions that have specific arguments but also use
> some subset of the globals as well.
>
> I guess the response is going to be: do not to use globals. I get that.
> However, to me it seems sometimes a natural and easy way to think about
> program a solution.
>
> What are the alternatives:
>
>    1. Live with poor performance
>    2. Create composite type containing the global variables, and pass
>    around a reference to single global variable of this composite type
>       - Would this boost performance?
>       - Would it boost performance if I didn't pass the composite-type
>       variable as argument, but instead access it inside functions as a global
>       variable?
>    3. What else?
>
>
>
> To compare performance, in some functions I assigned global variables to
> local variables annotated with type. Then used local variable in
> function. This produced a considerable speed-up, between 3-4x faster.
>
> function foo(arg1::arg1type, ...)
>     l_var1::var1type = g_var1
>     l_var2::var1type = g_var2
>     ...
>
>     x = l_var1 * ...
> end
>
>
>
> Can I do something like the following with equivalent speedup?
>
> function foo(arg1::arg1type, ...)
>     g_var1::var1type
>     g_var2::var2type
>     ...
>
>     x = g_var1 * ...
> end
>
> This would be sort of like declaring global variables as arguments to
> function but with types.
> Compiler could optimise. Runtime error if type not correct.
>
>
>
> As an aside, it occurred to me that there might be 2 cases for global
> variables.
>
>    1. globals used in interactive REPL environment, where global can be
>    reassigned
>    2. globals used for bad or lazy or whatever programming
>
> Why can't we have static *type* globals? Not const but const type.
> So effectively, we have 3 levels of const/variable-ness
>
> global x = 5
> x = 6     # OK
> x = 9.1   # OK
>
> static x = 5
> x = 6     # OK
> x = 9.1   # ERROR, must release/clear/reset x first
>
> const x = 5
> x = 6     # ERROR
> x = 9.1   # ERROR
>
>
>
>
> Cheers, Greg
>

Reply via email to