Dim
-
- Posts: 49
- Joined: Dec 16, 2011 3:48
Dim
If we DIm a variable at the beginning of a program as SHARED just once instead of DIming it in a function and call the function for example 100,000 times in running the program.( the DIM runs 100.000 times in the function).which way is better in programming?
Re: Dim
If you Dim a variable as Shared at the beginning of the program, then memory for the variable will only need to be allocated once (on the heap) and the variable will then be available to every procedure in the same module. Moreover, its value will be persisted during the execution of the program.
On the other hand if you Dim a local variable within a procedure, then memory for the variable will be allocated (either on the stack or within a CPU register) each time the procedure is called and the variable will only be available to that procedure. When the procedure returns, the variable will be destroyed.
Which is better programming depends on whether you actually want a variable to be available to all procedures in the same module as well as the module-level code itself. In most cases, you probably won't want this and consequently 'global' variables tend to be frowned upon in programming circles due to their lack of encapsulation.
However, in FreeBASIC you can in a sense 'have your cake and eat it' by declaring a variable to be 'Static' within a procedure. In this case, memory for the variable is only allocated once on the heap but its value persists between calls to the same procedure. Furthermore, its value is only available within that procedure, not to other procedures nor the module-level code. So, if you do want a persistent variable that is only available to its declaring procedure, 'Static' is the way to go :)
On the other hand if you Dim a local variable within a procedure, then memory for the variable will be allocated (either on the stack or within a CPU register) each time the procedure is called and the variable will only be available to that procedure. When the procedure returns, the variable will be destroyed.
Which is better programming depends on whether you actually want a variable to be available to all procedures in the same module as well as the module-level code itself. In most cases, you probably won't want this and consequently 'global' variables tend to be frowned upon in programming circles due to their lack of encapsulation.
However, in FreeBASIC you can in a sense 'have your cake and eat it' by declaring a variable to be 'Static' within a procedure. In this case, memory for the variable is only allocated once on the heap but its value persists between calls to the same procedure. Furthermore, its value is only available within that procedure, not to other procedures nor the module-level code. So, if you do want a persistent variable that is only available to its declaring procedure, 'Static' is the way to go :)
Re: Dim
No difference of execution time betwen the two configurations.
But if this variable is used by one procedure only (variable used locally), it is better to declare it inside the procedure (by DIM, or STATIC if the value must be kept from one call to another call).
But if this variable is used by one procedure only (variable used locally), it is better to declare it inside the procedure (by DIM, or STATIC if the value must be kept from one call to another call).
Re: Dim
Here are some samples.
Code: Select all
dim shared s as string
s=" Hello"
function dothis(s as string=" Hello") as string
var g=s
return g+s
end function
function dothat() as string
dim s as string =" Hello"
var g=s
return g+s
end function
function doother() as string
var g=s
return g+s
end function
function doagain() as string
static as string s
s=" Hello"
var g=s
return g+s
end function
dim as double t
dim as long limit=1000000
t=timer
for n as long=1 to limit
dothis
next n
print timer-t,dothis,"set as parameter"
t=timer
for n as long=1 to limit
dothat
next n
print timer-t,dothat,"set in sub"
t=timer
for n as long=1 to limit
doother
next n
print timer-t,doother,"set as shared"
t=timer
for n as long=1 to limit
doagain
next n
print timer-t,doagain,"set as static"
sleep
-
- Posts: 649
- Joined: Jun 09, 2005 0:08
Re: Dim
The number of variables declared inside a function wont change execution time, at the start of the function the base pointer is set to the current stack address and the number of bytes required for all the variables within the function is subtracted from the stack pointer (the stack goes downwards). Variables are then indexed off the base pointer. When the function ends the stack pointer is restored to its original value.
The operation is the same regardless of the number of variables, only a different number is subtracted from the stack pointer to give more or less space for variables.
Some variables in different scopes within the function might even share the same address.
Another point, if you declare a variable at the start of the function or within a scope but don't assign it a value then 0 is written to it which will take some small amount of time, if you dont care what its initial value is then you can use something like
Dim as integer a=any
Which assembles to nothing, it just tells the compiler that theres a variable a from that point onwards. The value in it could be anything though so be careful that you're not depending on it being initialised to 0
The operation is the same regardless of the number of variables, only a different number is subtracted from the stack pointer to give more or less space for variables.
Some variables in different scopes within the function might even share the same address.
Another point, if you declare a variable at the start of the function or within a scope but don't assign it a value then 0 is written to it which will take some small amount of time, if you dont care what its initial value is then you can use something like
Dim as integer a=any
Which assembles to nothing, it just tells the compiler that theres a variable a from that point onwards. The value in it could be anything though so be careful that you're not depending on it being initialised to 0
Re: Dim
Because local variables are allocated from the stack, and the stack is constantly being accessed, local variables are more likely to be in the cache.
Re: Dim
Example of reusing the same (stack) memory address in some different (procedure) scopes.
Code: Select all
Scope
Dim I As Integer
I = 123
Print @I, I
End Scope
Scope
Dim J As Integer
Print @J, J
J = 456
End Scope
Scope
Dim K As Integer = Any
Print @K, K
End Scope
Sleep
Code: Select all
Sub s1 ()
Dim I As Integer
I = 123
Print @I, I
End Sub
Sub S2 ()
Dim J As Integer
Print @J, J
J = 456
End Sub
Sub s3 ()
Dim K As Integer = Any
Print @K, K
End Sub
s1()
s2()
s3()
Sleep
-
- Posts: 2958
- Joined: Jun 02, 2015 16:24
Re: Dim
If the topic is not too busy, just testing a little tool.
It's not anyway to be off topic totally because it's of some use to improve the rendering of basic console texts, like in the example I grabbed from here, the dodicats snippet.
What is a pitty is that this still lacks a working file output, no values are shown for now.
Thanks anyway. Good review done about Dim! Remember that we can also VAR SHARED.
It's not anyway to be off topic totally because it's of some use to improve the rendering of basic console texts, like in the example I grabbed from here, the dodicats snippet.
What is a pitty is that this still lacks a working file output, no values are shown for now.
Thanks anyway. Good review done about Dim! Remember that we can also VAR SHARED.
Code: Select all
'********************
'bubbleflow :: help displaying a nice vertical text flow
'note::
'file named "temp.txt" created in the current running folder
'____________________________________________________________
nameSpace bubbleflow
'note that macros seems not namespace sensitive in any manner
#macro _STARTBUBBLEFLOW(fileName)
dim as string bubbleTextArray(any)
var fileId => fileName
var fileNum => freeFile()
open fileId for output as #fileNum
close #fileNum
?
var initialPosition => csrLin() - 1
var currentPosition => initialPosition
var bubbleHeight => -1
#endMacro
#macro _VARIADICTOSTRING( item0, items... )
( #item0 &";"& #items )
#endMacro
#macro _BUBBLEPRINT(text0, texts...)
scope
var w => width()
var colNum => loWord(w)
var rowNum => hiWord(w)
var fgdColor => 0
var bckColor => 0
if screenPtr()=0 then
fgdColor => loWord(color())
bckColor => hiWord(color())
else
screenControl 13, fgdColor, bckColor
end if
color bckColor, fgdColor
'push at screen
print space(colNum);
locate csrLin() - 1
print ##text0##texts
'push at array
redim preserve bubbleTextArray(uBound(bubbleTextArray) + 1)
bubbleTextArray(uBound(bubbleTextArray)) => _VARIADICTOSTRING(text0, texts...)
'
color fgdColor, bckColor
end scope
#endMacro
#macro _GETBUBBLE(bubbleTitle)
currentPosition = initialPosition
bubbleHeight = csrLin() - initialPosition - 1
locate initialPosition
scope
var w => width()
var colNum => loWord(w)
var rowNum => hiWord(w)
var fgdColor => 0
var bckColor => 0
if screenPtr()=0 then
fgdColor => loWord(color())
bckColor => hiWord(color())
else
screenControl 13, fgdColor, bckColor
end if
color bckColor, fgdColor
open fileId for append as #fileNum
for r as integer = 1 to iif(len(bubbleTitle)<colNum, colNum - len(bubbleTitle), 0)
? "%";
print #fileNum, "%";
next r
? iif(len(bubbleTitle)<colNum, bubbleTitle, left(bubbleTitle, colNum));
print #fileNum, iif(len(bubbleTitle)<colNum, bubbleTitle, left(bubbleTitle, colNum))
for h as integer = 0 to uBound(bubbleTextArray)
?
print #fileNum, bubbleTextArray(h)
next h
for r as integer = 1 to colNum
? "%";
print #fileNum, "%";
next r
for c as integer = 1 to 2
locate ,colNum\2 : ? "%"
print #fileNum, space(colNum\2); "%"
next c
close #fileNum
locate csrlin - 4 - 1 - bubbleHeight
color fgdColor, bckColor
end scope
initialPosition = initialPosition + bubbleHeight + 4
locate initialPosition + 1
erase bubbleTextArray
#endMacro
#macro _ENDBUBBLEFLOW()
scope
var w => width()
var colNum => loWord(w)
var rowNum => hiWord(w)
var fgdColor => 0
var bckColor => 0
if screenPtr()=0 then
fgdColor => loWord(color())
bckColor => hiWord(color())
else
screenControl 13, fgdColor, bckColor
end if
color bckColor, fgdColor
'
locate initialPosition + 0, colNum\2 - 1 : ? "%%%"
locate initialPosition + 1, colNum\2 - 1 : ? "end"
locate initialPosition + 2, colNum\2 - 1 : ? "%%%"
open fileId for append as #fileNum
print #fileNum, space(colNum\2 - 1); "%%%"
print #fileNum, space(colNum\2 - 1); "end"
print #fileNum, space(colNum\2 - 1); "%%%"
close #fileNum
'
color fgdColor, bckColor
end scope
#endMacro
end nameSpace
'********************
color 2, 11
dim shared as string s
s => "hello"
function DoThis(s as string="hello") as string
var g => s
return g & s
end function
function DoThat() as string
dim as string s => "hello"
var g => s
return g & s
end function
function DoOther() as string
var g => s
return g & s
end function
function DoAgain() as string
static as string s
s => "hello"
var g => s
return g & s
end function
'--------------------------------TEST
_STARTBUBBLEFLOW("temp.txt") ''start the text bubble flow
dim as double t => any
dim as integer limit => 1e+6
t = TIMER
for n as integer = 1 to limit
DoThat()
next n
_BUBBLEPRINT(TIMER - t; DoThat(); " set in sub")''replace the print statement
_GETBUBBLE("DoThat()") ''enclose the printed text in a cell
t = TIMER
for n as integer = 1 to limit
DoOther()
next n
_BUBBLEPRINT(TIMER - t; DoOther(); " set as shared")
_GETBUBBLE("DoOther()")
t = TIMER
for n as integer = 1 to limit
DoAgain()
next n
_BUBBLEPRINT(TIMER - t; DoAgain(); " set as static")
_GETBUBBLE("DoAgain()")
_ENDBUBBLEFLOW() ''mark the end of the running flow
getKey()
'(eof)