Solidity : How to compare strings?

Solidity does not offer string comparison out of the box.
If you search on Internet, you’ll see 2 implementations recommended.
Both use the keccak256 function to hash the string, but one uses bytes casting and the other one abi.encodePacked.
Which is the most efficient? Let’s check it out.

Here is the code used to compare both approaches:

pragma solidity ^0.8.7;

contract StringCompare {
  function encodedCompare(string calldata a, string calldata b) public returns (bool) {
    return keccak256(abi.encodePacked(a)) == keccak256(abi.encodePacked(b));
  }

  function castCompare(string calldata a, string calldata b) public returns (bool) {
    return keccak256(bytes(a)) == keccak256(bytes(b));
  }
}

Here are the tests I’m doing to check:

it('returns false if strings have not the same length', async function() {
  await contract.encodedCompare("1", "very long string that is big");
})

it('returns false if strings have not the same length', async function() {
  await contract.castCompare("1", "very long string that is big");
})

it('returns false if strings are not the same', async function() {
  await contract.encodedCompare("same length 1", "same length 2");
})

it('returns false if strings are not the same', async function() {
  await contract.castCompare("same length 1", "same length 2");
})

it('returns true if strings are the same', async function() {
  await contract.encodedCompare("same", "same");
})

it('returns false if strings are the same', async function() {
  await contract.castCompare("same", "same");
})

And here are the results:

FunctionMinMaxAvg
castCompare23,01023,26223,166
encodedCompare23,07223,32423,228

At the end of the day, casting is a slightly more efficient way to compare strings!