passing big string to procedures

Just starting out? Need help? Post your questions and find answers here.
spacewalker
User
User
Posts: 19
Joined: Tue Apr 27, 2010 4:35 pm
Location: Germany

passing big string to procedures

Post by spacewalker »

Hello,

I am new to PB and I have a question about passing a (big) string to a procedure:

As far as I understood it, strings are not passed ByRef, so this means that a string is copied when it is passed to a procedure?
So if I have a big string and pass it to a procedure - maybe several times - then it will cost much memory since the string is copied...?

Code: Select all

;Pseudo code;
BigString = ReadBigtextfile_to_String()  ;read 100MB textfile into string variable

MyProc1 (BigString)   ;will this copy 100MB to MyProc1 ?
MyProc2 (BigString)   ;will this copy again 100MB to MyProc2 ?

procedure myProc1 (MyString.s)
;do something with myString.s
endprocedure

procedure myProc2 (MyString.s)
;do something with myString.s
endprocedure

Thanks
User avatar
skywalk
Addict
Addict
Posts: 4211
Joined: Wed Dec 23, 2009 10:14 pm
Location: Boston, MA

Re: passing big string to procedures

Post by skywalk »

You can use:
Global.s Big$
procedure myProc1 ()
;do something with Big$
endprocedure

or

Put the big string in a structure:
Structure myStruc
Big$
endstructure
Global someStruc.myStruc

procedure myProc1 (*ptr.myStruc)
;do something with *ptr\Big$
endprocedure
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum
User avatar
luis
Addict
Addict
Posts: 3893
Joined: Wed Aug 31, 2005 11:09 pm
Location: Italy

Re: passing big string to procedures

Post by luis »

spacewalker wrote: As far as I understood it, strings are not passed ByRef, so this means that a string is copied when it is passed to a procedure?
Yes.
spacewalker wrote: So if I have a big string and pass it to a procedure - maybe several times - then it will cost much memory since the string is copied...?
It will cost time and the space for one copy.
The copy is destroyed when you left the proc.

To pass by reference you can do it this way:

Code: Select all

Define BigString.String 

BigString\s = "Hello"

Procedure MyProc (*MyString.String)
 Debug Len(*MyString\s) ; up to this point the string was not copied
 
 *MyString\s + " World!" ; now a new string is generated, so a copy takes place.
EndProcedure

Debug BigString\s

MyProc (@BigString)

Debug BigString\s


But as you can see maybe it's a false problem. If you only access the string to read it no copy is performed.
But as soon you start to use string functions on it, on concatenate with another, etc. new strings are created, potentially big or bigger then the source string.

So, the importance of this can be marginal, depends on what you do with the passed string.
"Have you tried turning it off and on again ?"
A little PureBasic review
spacewalker
User
User
Posts: 19
Joined: Tue Apr 27, 2010 4:35 pm
Location: Germany

Re: passing big string to procedures

Post by spacewalker »

Thank you both for the answers...using a global variable or a structure are good ideas.
But as you can see maybe it's a false problem. If you only access the string to read it no copy is performed.
But as soon you start to use string functions on it, on concatenate with another, etc. new strings are created, potentially big or bigger then the source string.

So, the importance of this can be marginal, depends on what you do with the passed string.
What I want to do with the passed string is to run a FindString () - so it's only a read process...
User avatar
kenmo
Addict
Addict
Posts: 2033
Joined: Tue Dec 23, 2003 3:54 am

Re: passing big string to procedures

Post by kenmo »

But... won't a new copy be created when it's passed to FindString()?
User avatar
skywalk
Addict
Addict
Posts: 4211
Joined: Wed Dec 23, 2009 10:14 pm
Location: Boston, MA

Re: passing big string to procedures

Post by skywalk »

Not if he uses CompareMemoryString() instead.
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum
User avatar
luis
Addict
Addict
Posts: 3893
Joined: Wed Aug 31, 2005 11:09 pm
Location: Italy

Re: passing big string to procedures

Post by luis »

kenmo wrote:But... won't a new copy be created when it's passed to FindString()?

Code: Select all

a$ = "hello"
FindString(a$, "he") 

Code: Select all

; a$ = "hello"
  MOV    edx,_S1
  LEA    ecx,[v_a$]
  CALL   SYS_FastAllocateStringFree
; FindString(a$, "he") 
  PUSH   dword _S2
  PUSH   dword [v_a$]
  CALL  _PB_FindString@8
From this I can't obviously know what's happening inside findstring but as you can see for both strings their address is pushed on the stack.
So probably the answer is "NO", considering findstring just needs to scan the string.
"Have you tried turning it off and on again ?"
A little PureBasic review
Post Reply