I have noticed that many functions that are meant to operate on string are slower compared to similar functions that operate on lists.
One example: Counts
versus LetterCounts
(and notice that the version with Counts
has to do two more tasks than version with LetterCounts
- it has to do ToCharacterCode
and then KeyMap
with FromCharacterCode
to transform the output to the LetterCounts
version)
SeedRandom[1]
str = RandomInteger[{1, 26}, 300] /.
Thread[Range[26] -> CharacterRange["A", "Z"]] // StringJoin;
LetterCounts[str, 2] // RepeatedTiming
KeyMap[FromCharacterCode,
Sort[Counts[Partition[ToCharacterCode[str], 2, 1]],
Greater]] // RepeatedTiming
(*{0.00426, <|"TT" -> 3, "IF" -> 3, "EP" -> 3, ... , "HA" -> 1, "AH" -> 1, "FA" -> 1|>}*)
(*{0.000830, <|"TT" -> 3, "IF" -> 3, "EP" -> 3, ... , "HA" -> 1, "AH" -> 1, "FA" -> 1|>}*)
The speed difference is significant!
Something is rotten in the state of Denmark Wolfram.