Skip to main content
added 1245 characters in body
Source Link
Jason B.
  • 70.2k
  • 3
  • 144
  • 298
LetterCounts[str, 2]

and

KeyMap[FromCharacterCode, 
  Sort[Counts[Partition[ToCharacterCode[str], 2, 1]], Greater]];

are not equivalent operations - just try the inputs found in the LetterCounts documentation and you'll quickly see differences. So the timing comparison is not very meaningful.

edit: To answer the question in the comments, the self-written

myCharacterCounts[str_, n_] := KeyMap[FromCharacterCode,
    Counts @ Partition[ToCharacterCode @ str, n, 1]
]

will run slightly faster than CharacterCounts[str, n], though on my machine the difference is sub-millisecond even for very large strings.

But this myCharacterCounts function still does not do everything that CharacterCounts does.

CharacterCounts takes options, as in

In[45]:= CharacterCounts["aAbBcC", IgnoreCase -> True]

Out[45]= <|"c" -> 2, "b" -> 2, "a" -> 2|>

and does argument checking, issuing a message for CharacterCounts[] or CharacterCounts[2]. Argument checking and options handling are generally required for any built-in system function, but not needed for self-written functions where you know you won't be passing bad arguments or options. This may be enough to account for the timing difference, or maybe CharacterCounts is being inefficient somewhere - I can't say.

I will say that it is often, but not always, possible to beat the timing for built-in functions if you focus on a subset of the functionality and neglect error handling. And if your application is time sensitive then it is worthwhile to use the custom function instead.

LetterCounts[str, 2]

and

KeyMap[FromCharacterCode, 
  Sort[Counts[Partition[ToCharacterCode[str], 2, 1]], Greater]];

are not equivalent operations - just try the inputs found in the LetterCounts documentation and you'll quickly see differences. So the timing comparison is not very meaningful.

LetterCounts[str, 2]

and

KeyMap[FromCharacterCode, 
  Sort[Counts[Partition[ToCharacterCode[str], 2, 1]], Greater]];

are not equivalent operations - just try the inputs found in the LetterCounts documentation and you'll quickly see differences. So the timing comparison is not very meaningful.

edit: To answer the question in the comments, the self-written

myCharacterCounts[str_, n_] := KeyMap[FromCharacterCode,
    Counts @ Partition[ToCharacterCode @ str, n, 1]
]

will run slightly faster than CharacterCounts[str, n], though on my machine the difference is sub-millisecond even for very large strings.

But this myCharacterCounts function still does not do everything that CharacterCounts does.

CharacterCounts takes options, as in

In[45]:= CharacterCounts["aAbBcC", IgnoreCase -> True]

Out[45]= <|"c" -> 2, "b" -> 2, "a" -> 2|>

and does argument checking, issuing a message for CharacterCounts[] or CharacterCounts[2]. Argument checking and options handling are generally required for any built-in system function, but not needed for self-written functions where you know you won't be passing bad arguments or options. This may be enough to account for the timing difference, or maybe CharacterCounts is being inefficient somewhere - I can't say.

I will say that it is often, but not always, possible to beat the timing for built-in functions if you focus on a subset of the functionality and neglect error handling. And if your application is time sensitive then it is worthwhile to use the custom function instead.

Source Link
Jason B.
  • 70.2k
  • 3
  • 144
  • 298

LetterCounts[str, 2]

and

KeyMap[FromCharacterCode, 
  Sort[Counts[Partition[ToCharacterCode[str], 2, 1]], Greater]];

are not equivalent operations - just try the inputs found in the LetterCounts documentation and you'll quickly see differences. So the timing comparison is not very meaningful.