Fastest way to check two strings same?

Hello there. I just wanted to ask what is the fastest way to check that two strings are the same. I need to return a decimal. (It’s for the Shakespearean monkey) . Since I want to run this with 1000 of populations I wanted to know if there is a more faster or declarative way of writing this.

Thanks

local totalCorrect = 0
local total = Guess:len()
for i = 1, total do
	if Guess:sub(i,i) == value:sub(i,i) then
		totalCorrect += 1
	end
end
return totalCorrect / total
3 Likes
local String1 = "Test"
local String2 = "Test"

if String1 == String2 then
     print("Same!")
end

You don’t need to parse through each character individually, you can just check the whole string (if I understand what you’re getting at, since value isn’t defined in the code snippet you gave)

I need to be able to get the percentage of correct characters in a string. This doesn’t do that.

To be honest I have run it on my machine and the code doesn’t seem to lag with 10 - 20 characters but for 100s of characters the code seems to break.

I believe this should be in #help-and-feedback:scripting-support - although you are showing code, you are asking a question, and so it might need to be in scripting support, though I may be wrong. But, the answer would be

local a = "Same";
local b = "Same";

if (a == b) then
   warn("A = B");
else
   warn("A != B");
end

If you want to know how many characters match then you have to compare every pair of characters, no way around it. Unless you know something about the strings to give you a hint, i.e. if they’re structured in some way.

One possible optimization might be to use string.byte instead of string.sub, since string.sub has to create a new string for every character and string.byte just looks at the actual bytes to compare each character without creating any strings. It might not make a difference though, who knows what optimizations there might be for string.sub, e.g. maybe if both indices are the same then it just uses string.byte anyway?

Give it a try though it might work

1 Like

Ohh, I just understood your question, here is my version:

local function shakespear(word, guess)
  local totalCorrect = 0
  local total = #guess
  local len = #word
  
  local strByte = string.byte
  
  for i = 1, len < total and len or total do
    if strByte(word, i, i) == strByte(guess, i, i) then
      totalCorrect = totalCorrect + 1
    end
  end
  
  return totalCorrect / total
end
  • Caching table lookups and globals before loops is a good practice generally
  • string.byte(str) is generally better than str:byte()
  • string.sub create new string while we’re not using it, so it goes to waste
  • for comparaison, string.byte is better as it returns just a number that respresents the character
  • No need to traverse the whole guess, if word is smaller than that
2 Likes

Thanks for this guy’s. It does seem to be faster now and it can definitely handle much larger strings without breaking.

1 Like