Если вы обрабатываете большие файлы (например, размером в несколько мегабайт), и эта операция абсолютно критична по скорости, то, возможно, имеет смысл выйти за рамки того, о чем вы спрашивали.В частности, следует учитывать, что посимвольная операция будет выполняться менее эффективно, чем при использовании SIMD-инструкций.
Т.е. если вы используете SSE2, вы можете кодировать toupper_parallel
(псевдокод):
for (cur_parallel_word = begin_of_block;
cur_parallel_word < end_of_block;
cur_parallel_word += parallel_word_width) {
/*
* in SSE2, parallel compares are either about 'greater' or 'equal'
* so '>=' and '<=' have to be constructed. This would use 'PCMPGTB'.
* The 'ALL' macro is supposed to replicate into all parallel bytes.
*/
mask1 = parallel_compare_greater_than(*cur_parallel_word, ALL('A' - 1));
mask2 = parallel_compare_greater_than(ALL('Z'), *cur_parallel_word);
/*
* vector op - and all bytes in two vectors, 'PAND'
*/
mask = mask1 & mask2;
/*
* vector op - add a vector of bytes. Would use 'PADDB'.
*/
new = parallel_add(cur_parallel_word, ALL('a' - 'A'));
/*
* vector op - zero bytes in the original vector that will be replaced
*/
*cur_parallel_word &= !mask; // that'd become 'PANDN'
/*
* vector op - extract characters from new that replace old, then or in.
*/
*cur_parallel_word |= (new & mask); // PAND / POR
}
Т.е. вы будете использовать параллельные сравнения, чтобы проверить, какие байты являются заглавными, а затем замаскировать как исходное значение, так и версию в верхнем регистре (один с маской, другой с обратным) перед вами или ими.вместе, чтобы сформировать результат.
Если вы используете доступ к файлу mmap, это может быть даже выполнено на месте, сохранено в буфере возврата и сохранено во многих функциях и / или системных вызовах.
Существует много возможностей для оптимизации, когда отправной точкой является посимвольный цикл 'fgetc' / 'fputc';даже утилиты оболочки, скорее всего, будут работать лучше, чем это.
Но я согласен, что если ваша потребность очень специального назначения (то есть что-то такое же четкое, как ввод ASCII для преобразования в верхний регистр), то цикл ручной работыкак указано выше, использование векторных наборов инструкций (таких как встроенные компоненты / сборка SSE, ARM NEON или PPC Altivec), вероятно, позволит значительно ускорить работу по сравнению с существующими утилитами общего назначения.