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:
Function | Min | Max | Avg |
castCompare | 23,010 | 23,262 | 23,166 |
encodedCompare | 23,072 | 23,324 | 23,228 |
At the end of the day, casting is a slightly more efficient way to compare strings!