From my understanding, the Stack is used to store value types (like Enumerations and Structures) and variables which are referenced to objects (like class instances) in the Heap. Furthermore, the Stack also holds function calls with their respective parameters and the like in a LIFO manner.
In C, there are 4 generic memory segments (Heap, Stack, Data, Code) where the Data segment(s) usually store the global and static variables which implies a completely separate aspect of memory where they are stored and managed, but I do believe Java handles it differently (with some magic on the part of the JVM).
How/where would a variable be stored if I declared a global variable in Swift? Would this be different if I simply played around with a Playground file, for example, compared to declaring a global/static variable/function in a project module in XCode?
Related
Does using anonymous function whenever possible reduces the memory usage and improves the overall performance in Dart?
Short Answer
No. It doesn't improve overall performance and also doesn't decrease memory usage. However the exact opposite might happen depending on the scenario.
Long Answer
Anonymous functions are the same as closures in Dart, and so will have a pointer(memory address) to the parent environment associated with it. Which means an additional variable with size equivalent to the bit-width of a pointer (in the corresponding platform) will be accompanying the anonymous function.
Memory
Here's how call to different types of functions work
Normal function: The arguments for the functions are the only values passed for the call.
Anonymous functions: The arguments for the functions are passed along with the pointer/reference to the parent's environment
Class method: A pointer/reference to the particular object instance is passed as the first argument along with the rest of the arguments.
Static Class method: This is equivalent to a normal function and the object instance of the class is not passed at all.
So, both class methods and anonymous functions have an extra variable, essentially a pointer, required to work. So "technically" this increases memory usage. However you don't have to worry about such things when you are using Dart. Because the extra memory required for anonymous functions and class methods is almost equivalent to when you add a new argument int newArg to a normal function or static class method.
If the anonymous function is executed right after it is declared, like (() {})(), then the pointer associated with it should be cleared in the next garbage collection sweep. This of course depends on the implementation and the scenario. If the anonymous function is stored in a variable or passed as an argument, then the lifetime of the pointer depends on the lifetime of that variable or argument.
Also, the pointer refers to the parent environment and because of this, the variables belonging to the parent scope, referred in the anonymous function will be kept alive even if the execution of the parent scope is complete. This in fact means that less memory is cleared in the next garbage collection sweep. The memory allocated for those referred variables will be cleared only when the anonymous function itself is not required anymore.
Performance
In the case of anonymous functions, there is also the need for lookup of parent-scoped variables used in the function body, that is the lookup for all the variables that are from the parent environment, this adds to compile-time or runtime depending on whether your dart code is AOT or JIT compiled.
But the same thing happens with normal class methods, as there is a need to lookup all class members used. (This doesn't happen in languages like Rust, Python... where there is a keyword like self or this representing the object instance that has to be explicitly mentioned)
Additional Context
Anonymous functions are otherwise referred to as lambdas or closures. There is actually a difference in definition between lambdas and closures
mathematically, and both of those can work as the other one depending on the use-case.
Lambdas are supposed to be functions that takes only one argument and has only one statement.
Closures are supposed to be functions that closes over the scope of its parent. Basically, closures can look for variables in the environment of its parent.
In Dart, there are no two entities separately known as lambdas and closures, instead there are closures. This is commonly seen in many programming languages, as they don't bother to keep a separation. By the way, the definition doesn't restrict a lambda from being a closure. And vice-versa.
I have seen the use of set keyword in tcl often. This cannot be used to create constant. How does one create constant in tcl which can then be used by other procedures?
Generally speaking, most of the uses of constants fall into several categories:
enumeration values
magical numbers
looping control factors
scaling factors
In Tcl, for the first case you'd usually just use the name instead of mapping it to an integer, with integer mappings only being applied in the cases that need them. Even bit sets can be handled that way, substituting a list of names for the set of bits (and the name being present in the list is equivalent to the bit being set). Tcl's C API has relevant functions for helping with this, specifically Tcl_GetIndexFromObj().
Magical values are usually best locked away close to the code that handles them. If I was interfacing to hardware, I'd not let the magic values appear at all at the script level (since I'd have the binding code written in C).
Looping control factors are often best represented as default values for procedure arguments, as they are things that you want to sometimes override. But they're often not as needed once custom control structures are available, and they fit a lot more into the Tcl style of working.
Scaling factors are the case where constants might be useful. I tend to simulate those by just using a global or namespace variable and plain old not assigning to it from elsewhere. I'd be quite interested in having code to allow constants (specifically variables that can't be assigned to) as a standard feature, but we don't have that right now.
Once those cases are covered, what remain tend to be unimportant constants. After all, there's almost no need to calculate the sizes of things for allocation and stuff like that, and things like positional binding in SQL statements are discouraged within TDBC in favour of binding by name (an awful lot easier to get right).
A simple way of making a constant is to put a write trace on a variable so that whenever it is written to, it is reset back to its constant value.
set CONSTANT 123
trace add variable CONSTANT write {apply {args {
global CONSTANT
# Reset to the constant value; write traces are after the fact
set CONSTANT 123
# Make the write give an error
error "may not change constant"
}}}
The Rust standard library has the std::mem::uninitialized function, which allows you to manually create an undefined (and possible invalid) value of any type. This essentially maps to LLVM's undef. I was wondering if Swift had an equivalent, as I haven't been able to find one skimming through the standard library documentation.
Motivation
The primary use for this is to bypass the compiler's normal memory initialization checks when they prove imprecise. For instance, you might want to initialize some members of a structure using methods (or in Swift's case, property setters), which the compiler usually would not allow you to do. Using dummy values works, but that's potentially less efficient (if the optimizer cannot prove that the dummy is meaningless).
In Rust, uninitialized values are treated as initialized by the initialization checker, but as uninitialized by LLVM, leading to more reliable optimization. Since the Swift compiler is also built atop LLVM, it seems like something the Swift compiler should also be able to support.
My Specific Use Case
I have a struct which encapsulates a set of bit fields compacted into one machine word (an unsigned integer type). The struct type provides a safe and convenient interface for reading and modifying the individual fields, through computed properties.
I also have an initializer that takes the relevant field values as parameters. I could initialize the underlying machine word using the same bitwise operations that the computed properties use (in which case I would be repeating myself), or I could initialize it simply by setting the values of the computed properties.
Currently, Swift does not support using computed properties before self has been fully initialized. It's also unlikely Swift will ever support this case, since the computed property setters modify the existing machine word, which would require it to already be initialized, at least as far as Swift is concerned. Only I know that all my setters, in concert, will fully initialize that machine word.
My current solution is to simply initialize the machine word to 0, and then run the setters. Since a constant 0 is trivially absorbed into the bitwise | chain that combines the fields, there's no CPU time lost, but that's always going to be the case. This is the kind of situation where, in Rust, I would have used an uninitialized value to express my intent to the optimizer.
In my iPhone development, I've always used global variables for lots of stuff. The style guide in my new job says we should use context parameters instead. So I need to figure out what that means and how to do that.
Can anyone explain in more detail what this means -- or point me to some code that works this way?
Thanks
It sounds like there may be a clash in nomenclature. From this definition of Context Parameters, they seem to be concerned storing global state for the duration of a session. Perhaps, you could use a 'contextParameters' NSDictionary within NSUserDefaults to store your globals. To the extent that your globals might need to be exported in their entirety (for debugging, for state saving) this might be useful in the long run.
The style guide might just be generically saying to keep your variables scoped based on the context of their usage. For example if you have a variable that you need for the lifetime of a class instance then make it a member variable of that class. If it is something that you need for the lifetime of the app then put it in an application wide object (but not a global variable).
If you use a global object (which could mostly be a big C struct containing all your former global variables) instead of individual naked global variables, you might be able to copy the object, serialize it to save it or create a unified core dump, eventually add setters/listeners, etc.
If you break the global object up, based on the shared scope or the required context of groupings of instance/struct variables, then the fractional objects might end up being good candidates for the M portion of an MVC repartitioning of your code for better reuse, extensibility, etc.
I am new to MATLAB, it wasn't in the job description and I've been forced to take over for the person who wrote and maintained the code my company uses. Life's tough.
The guy from which I'm taking over told me that he declared all the big data vectors as global, to save memory. More specifically, so that when one function calls another function, he doesn't create a copy of the data when he passes it over.
Is this true? I read Strategies for Efficient Use of Memory, and it says that
When working with large data sets, be aware that MATLAB makes a temporary copy of an input variable if the called function modifies its value. This temporarily doubles the memory required to store the array, which causes MATLAB to generate an error if sufficient memory is not available.
It says something very similiar in Memory Allocation For Array #Function Arguments:
When you pass a variable to a function, you are actually passing a reference to the data that the variable represents. As long as the input data is not modified by the function being called, the variable in the calling function and the variable in the called function point to the same location in memory. If the called function modifies the value of the input data, then MATLAB makes a copy of the original array in a new location in memory, updates that copy with the modified value, and points the input variable in the called function to this new array.
So is it true that using global can be better? It seems a little sloppy to blithely declare all the large data as global, instead of making sure that none of the code modifies its input argument. Am I wrong? Does this really improve RAM usage?
In my experience, provided that none of the code modifies the large data, memory usage is the same, regardless of whether you use a global variable or an input argument, just like the Matlab docs say. Further information is in this blog post by a MathWorks employee.
There is quite a bit of folklore on performance issues in Matlab and not all of it is right. The internals of Matlab have changed quite a bit. It may be that in a previous version it's better to use a global variable.
This answer may be somewhat tangential, but an additional topic that bears mention here is the use of nested functions to manage memory.
As has already been established in other answers, there is no need for global variables if the data you are passing to the function is not modified (since it will be passed by reference). If it is modified (and is thus passed by value), using a global variable instead will save you memory. However, global variables can be somewhat "uncouth" for the following reasons:
You have to make a declaration like global varName everywhere you need them.
It can be conceptually a little messy trying to keep track of when and how they are modified, especially if they are spread across multiple m-files.
The user can easily break your code with an ill-placed clear global, which clears all global variables.
An alternative to global variables was mentioned in the first set of documentation you cited: nested functions. Immediately following the quote you cited is a code example (which I've formatted slightly differently here):
function myfun
A = magic(500);
setrowval(400, 0);
disp('The new value of A(399:401,1:10) is')
A(399:401,1:10)
function setrowval(row, value)
A(row,:) = value;
end
end
In this example, the function setrowval is nested inside the function myfun. The variable A in the workspace of myfun is accessible within setrowval (as if it had been declared global in each). The nested function modifies this shared variable, thus avoiding any additional memory allocation. You don't have to worry about the user inadvertently clearing anything and (in my opinion) it's a bit cleaner and easier to follow than declaring global variables.
The solution seems a bit strange to me. As you found out already, it shouldn't have significant impact on the memory usage if the called function does not modify the data array. However, if the called function modifies the data array, there's a functional difference: In one case (making the data array global), the change has an impact on the rest of the code, in the other case (passing it as reference) the modifications are only local and temporary.
I think you pretty much answered your own question, but a couple more references would be good here:
I made a video on this:
http://blogs.mathworks.com/videos/2008/09/16/new-location-and-memory-allocation/
Similar to what Loren spoke of here:
http://blogs.mathworks.com/loren/2006/05/10/memory-management-for-functions-and-variables/
-Dogu