Fast string

Got an idea for enhancing PureBasic? New command(s) you'd like to see?
BarryG
Addict
Addict
Posts: 3292
Joined: Thu Apr 18, 2019 8:17 am

Re: Fast string

Post by BarryG »

+1 for faster native strings.
Cyllceaux
Enthusiast
Enthusiast
Posts: 458
Joined: Mon Jun 23, 2014 1:18 pm
Contact:

Re: Fast string

Post by Cyllceaux »

@forumuser

I don't know what you mean… do you have an example?

Btw. These are my string-tools at the moment.

Code: Select all

EnableExplicit

Procedure StringAppend(*sb,string.s)
	If string=""
		ProcedureReturn *sb
	EndIf
	Protected size,*Offset
	If *sb
		size=MemorySize(*sb)
		*Offset=size
	EndIf
	size+StringByteLength(string)
	*sb=ReAllocateMemory(*sb,size,#PB_Memory_NoClear)
	PokeS(*sb+*offset,string,-1,#PB_String_NoZero)
	ProcedureReturn *sb
EndProcedure

Procedure AppendString(*sb,string.s)
	ProcedureReturn StringAppend(*sb,string)
EndProcedure

Procedure.s SBToString(*sb)
	If *sb
		ProcedureReturn PeekS(*sb,MemorySize(*sb)/SizeOf(Character),#PB_Unicode)
	Else
		ProcedureReturn ""
	EndIf
EndProcedure

Macro SB2String(n)
	SBToString(n)
EndMacro

Procedure SBClear(*sb)
	If *sb
		FreeMemory(*sb)
	EndIf
	*sb=0
EndProcedure

Macro SBFree(n)
	SBClear(n)
EndMacro

ImportC ""
	wcsstr.i(*str1, *str2)
	_wcslwr.i(*cs)
	wcslen.l(*cs)
EndImport

Procedure FastStringSplit(sString.s, sDelimiters.s, Array StringArray.i(1), Casesense = 1)  
	
	Protected String = @sString
	Protected Delimiters = @sDelimiters
	
	Protected StringSize = wcslen(String) * 2
	Protected DelimitersSize = wcslen(Delimiters) * 2
	
	Protected aString = AllocateMemory(StringSize + 2):CopyMemory(String,aString,StringSize)
	If Not aString:ProcedureReturn 0:EndIf
	
	If Casesense = 0
		_wcslwr(String)
		_wcslwr(Delimiters)
	EndIf
	
	Protected String2 = String
	Protected ElementStart ,ElementSize
	
	Protected aItem
	Repeat   
		
		String2 = wcsstr(String2,Delimiters)
		If String2 = 0
			ElementSize = StringSize - ElementStart
		Else
			ElementSize = String2 - (String + ElementStart)
		EndIf
		
		If ArraySize(StringArray()) < aItem : ReDim StringArray(aItem +99):EndIf
		
		StringArray(aItem) = aString + ElementStart
		aItem + 1
		
		PokeW(aString + ElementStart + ElementSize, 0)
		
		ElementStart + ElementSize + DelimitersSize
		
		String2 + DelimitersSize
		
	Until String2 = DelimitersSize
	
	If ElementSize = StringSize
		FreeMemory(aString)
		If ArraySize(StringArray())=1
			StringArray(0)=@sString
		EndIf
		ProcedureReturn 0
	EndIf
	
	ReDim StringArray(aItem-1)
	
	If ArraySize(StringArray())=0
		StringArray(0)=@sString
	EndIf
	ProcedureReturn aString
EndProcedure

Procedure.s makeParsebleNumber(value.s,post.s="",prefix.s="")
	Protected result.s=Trim(ReplaceString(Value,#DQUOTE$,""))
	If post<>""
		result=ReplaceString(result,post,"")
	EndIf
	If prefix<>""
		result=ReplaceString(result,prefix,"")
	EndIf
	Protected pp=FindString(result,".")
	Protected kk=FindString(result,",")
	If pp<kk
		result=ReplaceString(result,".","")
		result=ReplaceString(result,",",".")
	Else
		result=ReplaceString(result,",","")
	EndIf
	ProcedureReturn Trim(result)
EndProcedure


Procedure.d extValD(value.s,post.s="",prefix.s="")
	Protected result.s=makeParsebleNumber(value)
	ProcedureReturn ValD(Trim(result))
EndProcedure

Procedure.f extValF(value.s,post.s="",prefix.s="")
	Protected result.s=makeParsebleNumber(value)
	ProcedureReturn ValF(Trim(result))
EndProcedure

Procedure.b isLong(value.s)
	ProcedureReturn Bool(Str(Val(value))=value)
EndProcedure
User avatar
DoubleDutch
Addict
Addict
Posts: 3219
Joined: Thu Aug 07, 2003 7:01 pm
Location: United Kingdom
Contact:

Re: Fast string

Post by DoubleDutch »

+1
https://deluxepixel.com <- My Business website
https://reportcomplete.com <- School end of term reports system
davido
Addict
Addict
Posts: 1890
Joined: Fri Nov 09, 2012 11:04 pm
Location: Uttoxeter, UK

Re: Fast string

Post by davido »

+1
DE AA EB
User avatar
chi
Addict
Addict
Posts: 1028
Joined: Sat May 05, 2007 5:31 pm
Location: Linz, Austria

Re: Fast string

Post by chi »

+1
Et cetera is my worst enemy
User avatar
Mijikai
Addict
Addict
Posts: 1360
Joined: Sun Sep 11, 2016 2:17 pm

Re: Fast string

Post by Mijikai »

+1
User avatar
Tenaja
Addict
Addict
Posts: 1948
Joined: Tue Nov 09, 2010 10:15 pm

Re: Fast string

Post by Tenaja »

+1
Rinzwind
Enthusiast
Enthusiast
Posts: 636
Joined: Wed Mar 11, 2009 4:06 pm
Location: NL

Re: Fast string

Post by Rinzwind »

Possibly take a look at http://bstring.sourceforge.net (or fork https://github.com/msteinert/bstring) for inspiration. Better String Library (bstrlib) for c.

Or https://github.com/antirez/sds . Simple Dynamic Strings (SDS), a c-string compatible optimized library by putting a header with length info in front of the actual c string which makes it an easy insert into PB I guess?
User avatar
Tenaja
Addict
Addict
Posts: 1948
Joined: Tue Nov 09, 2010 10:15 pm

Re: Fast string

Post by Tenaja »

I do not work with very large strings, but mostly under 64 characters. It would be nice if we could set the minimum length for the initial allocation, so there would typically be no additional allocations.

I'm also considering using ropes, skeptically. This might be useful, especially for those of you using very long strings. Basically, they are a List of shorter strings treated as a single string. Ideal for long sets, since it can eliminate your large repetitive allocations. Likely overkill for me though...
zikitrake
Addict
Addict
Posts: 834
Joined: Thu Mar 25, 2004 2:15 pm
Location: Spain

Re: Fast string

Post by zikitrake »

:lol: I thought I'd be alone in this fight.

+1 to have a faster native option of string concatenation
User avatar
pdwyer
Addict
Addict
Posts: 2813
Joined: Tue May 08, 2007 1:27 pm
Location: Chiba, Japan

Re: Fast string

Post by pdwyer »

This reminds me of the "Shlemiel the painter’s algorithm" from years (decades? ago)

https://www.joelonsoftware.com/2001/12/ ... to-basics/
Joel had a long and interesting rant about this topic. :lol:

It'd be nice for PB to perform this better since I've come to expect good performance under the hood on these kinds of things from the PB Team but it is something that can be (and often is) handled by the developer

+1
Paul Dwyer

“In nature, it’s not the strongest nor the most intelligent who survives. It’s the most adaptable to change” - Charles Darwin
“If you can't explain it to a six-year old you really don't understand it yourself.” - Albert Einstein
nsstudios
Enthusiast
Enthusiast
Posts: 274
Joined: Wed Aug 28, 2019 1:01 pm
Location: Serbia
Contact:

Re: Fast string

Post by nsstudios »

+1 for faster strings
User avatar
Tristano
Enthusiast
Enthusiast
Posts: 190
Joined: Thu Nov 26, 2015 6:52 pm
Location: Italy
Contact:

Re: Fast string

Post by Tristano »

Quite interesting, in this whole thread no one mentioned (nor tested) that PureBasic natively supports Fixed Strings ".s{Length}".

I'v rarely seen fixed-size strings used in real case examples, and I wonder if it has any benefits over "normal" strings.

Since the ".s{Length}" is a fixed width string, does it use Zero terminator? or does it store it's length somewhere?

I never quite understood why this alternative notation was added, and whether it has any benefits over the other notation.

Any ideas?
The PureBASIC Archives: FOSS Resources:
User avatar
Josh
Addict
Addict
Posts: 1183
Joined: Sat Feb 13, 2010 3:45 pm

Re: Fast string

Post by Josh »

Tristano wrote:... I wonder if it has any benefits over "normal" strings.
A 'normal' string is a pointer to a pointer to a memory area. Every time you change the string, this memory area is newly allocated.

A fix string is a pointer to a memory area that never changes. So the background overhead is much less. In structures a fixed string is stored directly in the structure.
Tristano wrote:Since the ".s{Length}" is a fixed width string, does it use Zero terminator? or does it store it's length somewhere?
With a fixed string you can use the full specified length. A reservation for a null terminator is not necessary. However, you can make the string shorter by using a null terminator.
sorry for my bad english
User avatar
Tenaja
Addict
Addict
Posts: 1948
Joined: Tue Nov 09, 2010 10:15 pm

Re: Fast string

Post by Tenaja »

A 'normal' string is a pointer to a pointer to a memory area. Every time you change the string, this memory area is newly allocated.
I believe it's only reallocated when necessary, not every time.
Post Reply