Küçük harfli ve büyük harfli alfabetik aralıklar %32
ASCII kodlama sisteminde bir "hizalama" sınırını geçmez .
Bu yüzden biraz 0x20
, aynı harfin büyük / küçük harf sürümleri arasındaki tek farktır.
Eğer durum bu değilse, 0x20
sadece geçiş yapmakla kalmayıp, toplama veya çıkarma yapmanız gerekir ve bazı harfler için diğer yüksek bitleri çevirmek için gerçekleştirme işlemi olur. (Geçiş yapabilecek tek bir işlem olmazdı ve ilk etapta alfabetik karakterleri kontrol etmek daha zor olurdu çünkü lcase'i zorlamak için | = 0x20 yapamazsınız.)
Yalnızca ASCII ile ilgili hileler: ile küçük harfe zorlayarak ve sonra (işaretsiz) olup olmadığını kontrol ederek alfabetik bir ASCII karakterinic |= 0x20
kontrol edebilirsiniz c - 'a' <= ('z'-'a')
. Yani sadece 3 işlem: VEYA + SUB + CMP sabit 25'e karşı. Elbette, derleyiciler (c>='a' && c<='z')
sizin için bu şekilde asm'i nasıl optimize edeceklerini biliyorlar , bu yüzden en fazla c|=0x20
kısmı kendiniz yapmalısınız . Özellikle imzalanacak varsayılan tamsayı promosyonları etrafında çalışmak için gerekli tüm dökümleri kendiniz yapmak oldukça sakıncalıdır int
.
unsigned char lcase = y|0x20;
if (lcase - 'a' <= (unsigned)('z'-'a')) {
}
Ayrıca bkz . C ++ 'daki Dizeyi Büyük Harfe Dönüştürme ( toupper
yalnızca ASCII için SIMD dizesi , bu denetimi kullanarak XOR için işleneni maskeleme.)
Ayrıca bir karakter dizisine nasıl erişilir ve küçük harfleri büyük harfe nasıl değiştirilir ve bunun tersi de geçerlidir
(SIMD içselleri ile C ve alfabetik ASCII karakterler için skaler x86 asm büyük / küçük harf çevirme, diğerlerini değiştirmeden bırakarak.)
Bu hileler çoğunlukla yalnızca SIMD ile bazı metin işlemeyi (örn. SSE2 veya NEON) elle optimize ediyorsanız yararlıdır. char
, bir vektördeki yüksek bit setine sahip . (Ve bu nedenle baytların hiçbiri, farklı büyük / küçük harf tersleri olabilecek tek bir karakter için çok baytlı UTF-8 kodlamasının parçası değildir). Herhangi birini bulursanız, bu 16 baytlık yığın için veya dizenin geri kalanı için skalere geri dönebilirsiniz.
Orada bazı yerel ayarlar bile vardır toupper()
ya tolower()
, özellikle Türk ı ı ↔ o aralığın dışında ASCII aralığı üretmek karakterler bazı karakterler ve İ ↔ i. Bu yerel ayarlarda, daha karmaşık bir kontrole ihtiyacınız olacak veya muhtemelen bu optimizasyonu hiç kullanmaya çalışmayacaksınız.
Ancak bazı durumlarda, UTF-8 yerine ASCII'yi varsaymanıza izin verilir, örneğin Unix yardımcı programları LANG=C
(POSIX yerel ayarı), değil en_CA.UTF-8
veya her neyse.
Ancak güvenli olduğunu doğrulayabilirseniz, toupper
orta uzunlukta dizeleri toupper()
bir döngü içinde aramadan çok daha hızlı yapabilirsiniz (5x gibi) ve son olarak Boost 1.58 ile test ettim , bu her karakter için aptalca olana göre çok daha hızlı .boost::to_upper_copy<char*, std::string>()
dynamic_cast
@
'' kullanarak^ 32
.