Page 4 of 5

Re: Fast string

Posted: Wed May 29, 2019 8:32 am
by BarryG
+1 for faster native strings.

Re: Fast string

Posted: Wed May 29, 2019 6:47 pm
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

Re: Fast string

Posted: Wed Jun 05, 2019 8:42 pm
by DoubleDutch
+1

Re: Fast string

Posted: Wed Jun 05, 2019 8:52 pm
by davido
+1

Re: Fast string

Posted: Wed Aug 14, 2019 4:31 pm
by chi
+1

Re: Fast string

Posted: Wed Aug 14, 2019 5:15 pm
by Mijikai
+1

Re: Fast string

Posted: Thu Aug 15, 2019 5:07 pm
by Tenaja
+1

Re: Fast string

Posted: Fri Aug 16, 2019 4:40 am
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?

Re: Fast string

Posted: Fri Aug 16, 2019 3:00 pm
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...

Re: Fast string

Posted: Mon Nov 11, 2019 8:59 pm
by zikitrake
:lol: I thought I'd be alone in this fight.

+1 to have a faster native option of string concatenation

Re: Fast string

Posted: Tue Jan 14, 2020 1:06 pm
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

Re: Fast string

Posted: Sat Jan 25, 2020 1:35 pm
by nsstudios
+1 for faster strings

Re: Fast string

Posted: Sat Feb 08, 2020 6:45 pm
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?

Re: Fast string

Posted: Sat Feb 08, 2020 8:29 pm
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.

Re: Fast string

Posted: Sat Feb 08, 2020 9:54 pm
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.