• gmod_game: Better/shorter string.Explode suggested by TomyLob..
    4 replies, posted
[B]Revision 875[/B] [INDENT]Better/shorter string.Explode suggested by TomyLobo[/INDENT] [B]Changed Files:[/B] [LIST] [*][URL="https://facepunch.svn.beanstalkapp.com/gmodgame/trunk/lua/includes/extensions/string.lua"]trunk/lua/includes/extensions/string.lua[/URL] [/LIST] Committed By [B]Alexander Overvoorde[/B]
You committed the wrong one, without the modifications I sent you later. Also, in the meantime, Divran found out that this version sucks for long strings so I wrote another one that performs much better for long strings but worse for short ones and he combined the two into this: --snip-- divran did some more benchmarks, he'll post an optimized version of of that 2nd version in a minute Just in case Divran's pastebin disappears, here's a gist mirror: [url]https://gist.github.com/TomyLobo/a51be4b0b95c3db9bfdcefae35b62e24[/url]
Here are some test results. "Explode1" is one with both of the two explode functions described below, with a string length check (see the code above). "Explode2" is the one with only the "()" .. sep .. "()" pattern. "Explode3" is the one with the "(.-)" .. sep .. "()" pattern. Test results: [url]http://pastebin.com/6wQP9MSq[/url] This means that #3 (the one with the "(.-) .. ()" pattern) is faster than #2 (the one with "() .. ()") when the parts in between the separators are very short. The length of the string does not matter. The time #3 takes to finish depend on the length of the parts. When they get bigger, the function gets slower. #2 does not suffer from this at all and runs at a constant speed pretty much all the time. It runs slightly slower when there are multiple separators in the string, but that's barely noticeable. I'd go with #2. EDIT: I just tried localizing string.sub at the top, and that made #2 another 0.01 seconds faster when running the third test. And by the way, here's the final code: [lua]local totable = string.ToTable local string_sub = string.sub local string_gsub = string.gsub local string_gmatch = string.gmatch function string.Explode(separator, str, withpattern) if (separator == "") then return totable( str ) end local ret = {} local index,lastPosition = 1,1 -- Escape all magic characters in separator if not withpattern then separator = string_gsub( separator, "[%-%^%$%(%)%%%.%[%]%*%+%-%?]", "%%%1" ) end -- Find the parts for startPosition,endPosition in string_gmatch( str, "()" .. separator.."()" ) do ret[index] = string_sub( str, lastPosition, startPosition-1) index = index + 1 -- Keep track of the position lastPosition = endPosition end -- Add last part by using the position we stored ret[index] = string_sub( str, lastPosition) return ret end[/lua]
Alright, but this is the last time I'm going to change it.
Please use this for string.Replace, your one doesn't stop the pattern patching properly. [lua] local MAGIC_CHARACTERS = "([%(%)%.%%%+%-%*%?%[%^%$])"; function string.Replace(text, find, replace) return ( text:gsub(find:gsub(MAGIC_CHARACTERS, "%%%1"), replace) ); end; [/lua]
Sorry, you need to Log In to post a reply to this thread.