Page 1 of 1
passing big string to procedures
Posted: Thu Jun 06, 2013 3:30 pm
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
Re: passing big string to procedures
Posted: Thu Jun 06, 2013 3:47 pm
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
Re: passing big string to procedures
Posted: Thu Jun 06, 2013 3:54 pm
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.
Re: passing big string to procedures
Posted: Thu Jun 06, 2013 4:52 pm
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...
Re: passing big string to procedures
Posted: Fri Jun 07, 2013 12:11 am
by kenmo
But... won't a new copy be created when it's passed to FindString()?
Re: passing big string to procedures
Posted: Fri Jun 07, 2013 12:26 am
by skywalk
Not if he uses CompareMemoryString() instead.
Re: passing big string to procedures
Posted: Fri Jun 07, 2013 12:39 am
by luis
kenmo wrote:But... won't a new copy be created when it's passed to FindString()?
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.