Dim

New to FreeBASIC? Post your questions here.
student1347
Posts: 49
Joined: Dec 16, 2011 3:48

Dim

Postby student1347 » Nov 08, 2016 16:23

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?
FreeFox
Posts: 69
Joined: Sep 28, 2016 23:45

Re: Dim

Postby FreeFox » Nov 08, 2016 17:53

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 :)
fxm
Posts: 9123
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Dim

Postby fxm » Nov 08, 2016 18:00

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).
dodicat
Posts: 5913
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Dim

Postby dodicat » Nov 08, 2016 18:00

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





 
Stonemonkey
Posts: 549
Joined: Jun 09, 2005 0:08

Re: Dim

Postby Stonemonkey » Nov 08, 2016 18:38

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
MichaelW
Posts: 3500
Joined: May 16, 2006 22:34
Location: USA

Re: Dim

Postby MichaelW » Nov 08, 2016 20:24

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.
fxm
Posts: 9123
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Dim

Postby fxm » Nov 08, 2016 20:29

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
Tourist Trap
Posts: 2762
Joined: Jun 02, 2015 16:24

Re: Dim

Postby Tourist Trap » Nov 08, 2016 21:20

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.

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)

Return to “Beginners”

Who is online

Users browsing this forum: No registered users and 4 guests