Если ваша «начинка» должна содержать только «0» - «9», «A» - «Z» и «a» - «z» и в некоторой кодировке основана на ASCII (как большинство кодировок на основе Unicode), тогда вы можете пропустить два сравнения в одном из ваших циклов, поскольку только один бит различается между заглавными и второстепенными символами.
Вместо
ch>='0' && ch<='9' && ch>='A' && ch<='Z' && ch>='a' && ch<='a'
вы получите
ch2 = ch & ~('a' ^ 'A')
ch>='0' && ch<='9' && ch2>='A' && ch2<='Z'
Но вам лучше взглянуть на код ассемблера, сгенерированный вашим компилятором, и провести некоторый сравнительный анализ, в зависимости от архитектуры компьютера и компилятора, этот прием может дать более медленный код.
Если ветвление стоит дороже по сравнению со сравнениями на вашем компьютере, вы также можете заменить &&
на &
. Но большинство современных компиляторов знают этот трюк в большинстве ситуаций.
Если, с другой стороны, вы проверяете любой печатный глиф из какой-либо крупной кодировки символов, то, скорее всего, дешевле проверить глифы с пробелами, чем печатный глиф.
Кроме того, скомпилируйте специально для компьютера, на котором будет выполняться код, и не забывайте о любом поколении кода отладки.
Добавлено:
Не совершайте подпрограммных вызовов в циклах сканирования, если это того не стоит.
Какой бы трюк вы ни использовали для ускорения своих циклов, он уменьшится, если вам придется выполнять подпрограммный вызов в одном из них. Хорошо использовать встроенные функции, которые ваш компилятор встроит в ваш код, но если вы используете что-то вроде внешней библиотеки регулярных выражений, и ваш компилятор не может встроить эти функции (gcc может сделать это иногда, если вы попросите это ), затем выполнение этого вызова подпрограммы будет перетасовывать много памяти, в худшем случае между различными типами памяти (регистры, буферы ЦП, ОЗУ, жесткий диск и т. д.) и может испортить прогнозы ЦП и конвейеры. Если ваши текстовые фрагменты не очень длинные, и вы тратите много времени на их анализ, а подпрограмма достаточно эффективна, чтобы компенсировать стоимость вызова, не делайте этого. Некоторые функции для синтаксического анализа используют обратные вызовы, это может быть более эффективным, чем выполнение большого количества подпрограммных вызовов из ваших циклов (поскольку функция может сканировать несколько совпадений с шаблоном за один цикл и объединять несколько обратных вызовов вне критического цикла) , но это зависит от того, как кто-то другой написал эту функцию, и в основном это то же самое, что вы делаете вызов.