In C is it faster to use the standard library or write your own function?
Unless you have specific reason to do so (e.g., you have a specific requirement not to use the standard library or you've profiled a very specific use case where you can write a function that performs better), you should always prefer to use a standard library function where one exists rather than writing your own function.
The standard library functions are heavily optimized and very well tested. In addition, the standard library that ships with your compiler can take advantage of compiler intrinsics and other low-level details that you can't portably use in your own code.
isalpha
does not merely check if its argument is in the ranges A-Z
, a-z
. Quoting the C standard (§7.4.1.2):
The isalpha function tests for any character for which isupper or islower is true, or any character that is one of a locale-specific set of alphabetic characters for which none of iscntrl, isdigit, ispunct, or isspace is true.
In all likelihood you can write a more limited version (as you suggest) that is faster for the subset of cases that it handles, but it won't be the isalpha
function. Library routines exist not only to be efficient, but to be complete and correct. Efficiency actually turns out to be the easy part; getting all the edge cases right is where the hard work comes in.
Note also, if you're going to write an optimized version that targets English/ASCII, you can do it rather more efficiently then what you suggested, either with the lookup table that someone else suggested, or my personal preference (edited to fix an error caught by R..)
int isalpha(int c) {
return ((unsigned int)(c | 32) - 97) < 26U;
}
Generally, you should always use the C libraries when possible. One real reason not to is when you are in an embedded environment and are EXTREMELY space limited (which is usually not the case, and virtually all embedded platforms provide C libraries for the platform).
An example may be that using the isalpha
function may actually drag in an object file containing all of the is...
functions and you don't need any of them (the object file is the typical minimum unit when linking although some linkers can go down to individual functions).
By writing your own isalpha
, you can ensure that it, and only it, is incorporated into your final binary.
In some limited cases you may get faster speeds where you have a very specific thing you are wanting to do and the library is handling a more general case. Again, only needed if a particular loop is a bottleneck in the system. You may also want to choose a different speed/space tradeoff than that chosen by the library writer, an example being changing:
int isalpha (int c) {
return ((c >= 'A') && (c <= 'Z')) || ((c >= 'a') && (c <= 'z'));
}
into:
int isalpha (int c) {
static int map[256] = {0,0,0,0,...,1,1,1,...,0,0,0};
return map[c & 0xff];
}
a (potentially) faster implementation at the cost of extra storage for the map (and you need to understand your execution environment since it's not portable).
Another reason not to use them is to provide a more secure way with dealing with things like strings where security/robustness is a CRITICAL factor. This will generally cost you a lot more time to prove the correctness.