Get String Characters 4x Faster than Mid()

Post your FreeBASIC source, examples, tips and tricks here. Please don’t post code without including an explanation.
Munair
Posts: 1286
Joined: Oct 19, 2017 15:00
Location: Netherlands
Contact:

Re: Get String Characters 4x Faster than Mid()

Post by Munair »

fxm wrote:@Munair,

But nobody is obliged to use this type of syntax, as I said myself in the next post:
fxm (https://www.freebasic.net/forum/viewtopic.php?p=186884#p186884) wrote:As for me, I will prefer always to use (pz as zstring ptr):
*pz or pz for a zstring
(*pz) or pz[j] for an ubyte

True, and I agree with you on choosing the 'right' syntax.
fxm
Moderator
Posts: 12081
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Get String Characters 4x Faster than Mid()

Post by fxm »

Do not write after the first zero of the string.

Code: Select all

dim as string * 32 z = "hello"


dim as zstring ptr pz = @z[0]  'simpler: = @z
pz[2][3]=asc("X")
print z

pz[5]=asc("Y")
print z
sleep  
dodicat
Posts: 7976
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Get String Characters 4x Faster than Mid()

Post by dodicat »

@z gives me a Suspicious pointer assignment in 1.05
fxm
Moderator
Posts: 12081
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Get String Characters 4x Faster than Mid()

Post by fxm »

Excuse me, you are right.
But @z[0] returns an Ubyte Ptr.
The best syntax (IMHO) is:
dim as zstring ptr pz = strptr(z)
Munair
Posts: 1286
Joined: Oct 19, 2017 15:00
Location: Netherlands
Contact:

Re: Get String Characters 4x Faster than Mid()

Post by Munair »

dodicat wrote:@z gives me a Suspicious pointer assignment in 1.05
Use STRPTR instead:

Code: Select all

dim as string * 32 z = "hello"


dim as zstring ptr pz = strptr(z)  'simpler: = @z
pz[2][3]=asc("X")
print z

pz[5]=asc("Y")
print z
sleep 
EDIT: (sorry fxm, our posts crossed).
marpon
Posts: 342
Joined: Dec 28, 2012 13:31
Location: Paris - France

Re: Get String Characters 4x Faster than Mid()

Post by marpon »

Munair wrote:
dodicat wrote:@z gives me a Suspicious pointer assignment in 1.05
Use STRPTR instead:

Code: Select all

dim as string * 32 z = "hello"


dim as zstring ptr pz = strptr(z)  'simpler: = @z
pz[2][3]=asc("X")
print z

pz[5]=asc("Y")
print z
sleep 
in that case with z as string * 32 better to use varptr(z) or @(z)

strptr is intended to be used by dynamic strings (even strptr works also in that case , i think is better not confuse with that usage)

Code: Select all

dim as string * 32 z = "hello"
dim as zstring ptr pz = varptr(z)  'simpler and equivalent : = @z
pz[5]=asc("Y")
print z
sleep 
Munair
Posts: 1286
Joined: Oct 19, 2017 15:00
Location: Netherlands
Contact:

Re: Get String Characters 4x Faster than Mid()

Post by Munair »

marpon wrote:in that case with z as string * 32 better to use varptr(z) or @(z)

strptr is intended to be used by dynamic strings (even strptr works also in that case , i think is better not confuse with that usage)

Code: Select all

dim as string * 32 z = "hello"
dim as zstring ptr pz = varptr(z)  'simpler and equivalent : = @z
pz[5]=asc("Y")
print z
sleep 
No, as the assignment is to a zstring ptr, STRPTR should be used, which returns the same type and points to the string data. VARPTR raises the same warning as @ because they return a different pointer type (to the descriptor in the case of string).
Munair
Posts: 1286
Joined: Oct 19, 2017 15:00
Location: Netherlands
Contact:

Re: Get String Characters 4x Faster than Mid()

Post by Munair »

Alternatively, SADD can also be used. It returns the same data type and offset as STRPTR.
nimdays
Posts: 236
Joined: May 29, 2014 22:01
Location: West Java, Indonesia

Re: Get String Characters 4x Faster than Mid()

Post by nimdays »

fxm wrote:

Code: Select all

dim as string * 32 z = "hello"
dim as zstring ptr pz = @z[0]  'simpler: = @z
pz[2][3]=asc("X")
print z
Just curious about acessing the index here.

Code: Select all

dim as string * 32 z = "hello"
dim as zstring ptr pz = @z[0]  'simpler: = @z
pz[2][3]=asc("X")
print z
' and this one
pz[3][2]=asc("X")
print z
Munair
Posts: 1286
Joined: Oct 19, 2017 15:00
Location: Netherlands
Contact:

Re: Get String Characters 4x Faster than Mid()

Post by Munair »

nimdays wrote:Just curious about acessing the index here.

Code: Select all

dim as string * 32 z = "hello"
dim as zstring ptr pz = @z[0]  'simpler: = @z
pz[2][3]=asc("X")
print z
' and this one
pz[3][2]=asc("X")
print z
The first index points to the string data, so pz[2] would point to the first 'l' in 'hello'. The second index is the offset from that string data, so pz[2][3] would point to the 6th character. This would be equivalent to pz[5]=asc("X").
nimdays
Posts: 236
Joined: May 29, 2014 22:01
Location: West Java, Indonesia

Re: Get String Characters 4x Faster than Mid()

Post by nimdays »

@Munair, Thanks
fxm
Moderator
Posts: 12081
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Get String Characters 4x Faster than Mid()

Post by fxm »

Note
In the expression:
pz[2][3]
the two '[]' operators are not of the same type.
The expression is evaluated as following:
(pz[2])[3]
The first '[]' (from left to right) is the pointer index operator which allows to dereference the 'Zstring Ptr' ('pz') to provide a reference to a sub-string of 'z' beginning at the offset '2'.
The second '[]' (from left to right) is the string index operator which allows to return a reference to a character of the previous sub-string ('pz[2]') located at the offset '3'.
Lost Zergling
Posts: 534
Joined: Dec 02, 2011 22:51
Location: France

Re: Get String Characters 4x Faster than Mid()

Post by Lost Zergling »

A related post here : https://freebasic.net/forum/viewtopic.php?f=7&t=26616 and fxm's explanations.
I discovered there were different assignment level and how to access them.
dodicat wrote "looks like the sub keeps the literal addresses on the stack ... Which probably means that you can only pass literals a finite number of times."
Some words about speeds : in my lzle, I'm using a ubyte assignment level in combination with Swap.
The purpose of swap in this context (in my mind) is to make a local variable "virtually static" in memory so as to minimize stack calls and/or backend dealloc/realloc. I see it as if using stack was a little bit like using processor cache...partially thrue I think.
Same spirit is the pseudo-recursive concept (parsing a tree not using or using as less as possible processor's stack).
"Cache oblivious" : related thematic recently found on the Internet.
MrSwiss
Posts: 3910
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: Get String Characters 4x Faster than Mid()

Post by MrSwiss »

[off topic]
Lost Zergling wrote:The purpose of swap in this context (in my mind) is to make a local variable "virtually static" in memory so as to minimize stack calls and/or backend dealloc/realloc. I see it as if using stack was a little bit like using processor cache...partially thrue I think
Swap just does, what it is expected to do (no more, no less):

Swap var_type1, var_type2 (var_type(n) means: any FB intrinsic data-type)
the values held by any var_type(n) are simply exchanged ...
result = var_type1 has now the value, previously held by var_type2 (and, vice-versa).

Code: Select all

Dim As String   s1 = "a", s2 = "z"
Dim As Long     l1 = 123456, l2 = -654321

Print s1; "   "; s2
Print l1; "   "; l2
Sleep

Swap s1, s2 : Swap l1, l2

Print s1; "   "; s2
Print l1; "   "; l2
Sleep
[/off topic]
MrSwiss
Posts: 3910
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: Get String Characters 4x Faster than Mid()

Post by MrSwiss »

on topic, again:

pz[j] notation, should IMO only be used on a:

ZString Ptr Ptr (a ZString Ptr array, with char access)
used as follows:
*pz for the whole ZString and,
pz[j] for a char (UByte)

on ZString Ptr, the notation should be:
*pz for the whole ZString and,
pz[i + j] for a char (UByte)
Post Reply