Что такое код strtoupper


Содержание

mb_strtoupper отображает знак вопроса

Привет у меня проблема с преобразованием специальных символов в верхний регистр.

С обычной strtoupper я получаю что-то вроде DANIëL, а при применении mb_strtoupper я получаю DANI? L.
Вот код:
mb_strtoupper (rtrim ($ штук [1], «,»), ‘UTF-8’)

Имейте в виду, у меня уже есть это работает на входе:
iconv (‘UTF-8’, ‘ISO-8859-1 // TRANSLIT’, $ tr-> TD [0])

Может ли это быть причиной? Или есть что-то еще?

Решение

Типичная проблема с попыткой заглавной буквы Latin1, когда конвертер ожидает UTF-8

Обязательно проверьте ваш источник строки. Этот пример будет работать, если ваш текстовый редактор работает с кодом страницы Latin1, и не в UTF-8

String. To Upper Метод

Определение

Возвращает копию этой строки, переведенную в верхний регистр. Returns a copy of this string converted to uppercase.

Перегрузки

Возвращает копию этой строки, переведенную в верхний регистр, используя правила определения регистра заданного языка и региональных параметров. Returns a copy of this string converted to uppercase, using the casing rules of the specified culture.

Возвращает копию этой строки, переведенную в верхний регистр. Returns a copy of this string converted to uppercase.

ToUpper(CultureInfo)

Возвращает копию этой строки, переведенную в верхний регистр, используя правила определения регистра заданного языка и региональных параметров. Returns a copy of this string converted to uppercase, using the casing rules of the specified culture.

Параметры

Объект, задающий правила определения регистра для языка и региональных параметров. An object that supplies culture-specific casing rules.

Возвраты

Эквивалент текущей строки в верхнем регистре. The uppercase equivalent of the current string.

Исключения

Свойство culture имеет значение null . culture is null .

Примеры

В следующем примере строка строчных символов преобразуется в две строки символов верхнего регистра с помощью языков и региональных параметров «Английский-США» и турецкого Турция, а затем сравниваются строки верхнего регистра. The following example converts a string of lowercase characters to two strings of uppercase characters using the English-United States and Turkish-Turkey cultures, then compares the uppercase strings. Строки в верхнем регистре идентичны, за исключением того, что для каждого вхождения ПРОПИСной буквы Юникода I в одной строке другая строка содержит ПРОПИСную БУКВу I с ТОЧКОЙ выше. The uppercase strings are identical except that for each occurrence of the Unicode LATIN CAPITAL LETTER I in one string, the other string contains LATIN CAPITAL LETTER I WITH DOT ABOVE.

Комментарии

Правила учета регистра языка и региональных параметров, заданные параметром culture , определяют способ изменения регистра строки. The casing rules of the culture specified by the culture parameter determine the way the case of a string is changed.

Этот метод не изменяет значение текущего экземпляра. This method does not modify the value of the current instance. Вместо этого возвращается новая строка, в которой все символы в текущем экземпляре преобразуются в верхний регистр. Instead, it returns a new string in which all characters in the current instance are converted to uppercase.

Вопросы безопасности Security Considerations

Если методу ToUpper(CultureInfo) передается объект CultureInfo, отличный от CultureInfo.InvariantCulture, то операция с регистром учитывает правила, зависящие от языка и региональных параметров. If you pass the ToUpper(CultureInfo) method a CultureInfo object other than CultureInfo.InvariantCulture, the casing operation will take culture-specific rules into account. Если требуется версия идентификатора операционной системы в нижнем регистре или в верхнем регистре, например имя файла, именованный канал или раздел реестра, используйте метод ToLowerInvariant или ToUpperInvariant. If you need the lowercase or uppercase version of an operating system identifier, such as a file name, named pipe, or registry key, use the ToLowerInvariant or ToUpperInvariant method. Это дает тот же результат в каждой культуре и работает более эффективно. This produces the same result in every culture and performs more efficiently.

Дополнительно

ToUpper()

Возвращает копию этой строки, переведенную в верхний регистр. Returns a copy of this string converted to uppercase.

Возвраты

Эквивалент текущей строки в верхнем регистре. The uppercase equivalent of the current string.

Примеры

В следующем примере вызывается метод ToUpper для преобразования ряда односимвольных строк, которые содержат каждый символ в наборе символов «базовый Латинский», «Латиница-1» и «латиница» расширенной кодировки. The following example calls the ToUpper method to convert a series of one-character strings that contain each character in the Basic Latin, Latin-1 Supplement, and Latin Extended-A character sets. Затем она отображает каждую строку, чей символ в верхнем регистре отличается от символа нижнего регистра. It then displays each string whose uppercase character is different from its lowercase character.

Комментарии

Этот метод использует правила регистра текущего языка и региональных параметров для преобразования каждого символа в текущем экземпляре в эквивалент в верхнем регистре. This method uses the casing rules of the current culture to convert each character in the current instance to its uppercase equivalent. Если символ не имеет эквивалента в верхнем регистре, он включается в возвращаемую строку без изменений. If a character does not have an uppercase equivalent, it is included unchanged in the returned string.

Этот метод не изменяет значение текущего экземпляра. This method does not modify the value of the current instance. Вместо этого возвращается новая строка, в которой все символы в текущем экземпляре преобразуются в верхний регистр. Instead, it returns a new string in which all characters in the current instance are converted to uppercase.

Метод ToUpper часто используется для преобразования строки в верхний регистр, чтобы ее можно было использовать в сравнении без учета регистра. The ToUpper method is often used to convert a string to uppercase so that it can be used in a case-insensitive comparison. Лучшим методом для выполнения сравнения без учета регистра является вызов метода сравнения строк, имеющего параметр StringComparison, значение которого равно StringComparison.CurrentCultureIgnoreCase для сравнения с учетом языка и региональных параметров, сравнение без учета регистра. A better method to perform case-insensitive comparison is to call a string comparison method that has a StringComparison parameter whose value you set to StringComparison.CurrentCultureIgnoreCase for a culture-sensitive, case-insensitive comparison.

Вопросы безопасности Security Considerations

Операция с регистром регистра, полученная в результате вызова метода ToUpper(), учитывает соглашения о регистре текущего языка и региональных параметров. The casing operation that results from calling the ToUpper() method takes the casing conventions of the current culture into account. Если требуется версия идентификатора операционной системы в нижнем регистре или в верхнем регистре, например имя файла, именованный канал или раздел реестра, используйте метод ToLowerInvariant или ToUpperInvariant. If you need the lowercase or uppercase version of an operating system identifier, such as a file name, named pipe, or registry key, use the ToLowerInvariant or ToUpperInvariant method. Это дает тот же результат в каждом языке и региональных параметрах (в отличие от метода ToUpper()) и работает более эффективно. This produces the same result in every culture (unlike the ToUpper() method) and performs more efficiently.

Илон Маск рекомендует:  Что такое код creat

Примечания для тех, кто вызывает этот метод

Как описано в статье рекомендации по использованию строк, рекомендуется избегать вызова методов регистра строк, которые заменяют значения по умолчанию, а вызывают методы, для которых требуется явно указать параметры. As explained in Best Practices for Using Strings, we recommend that you avoid calling string casing methods that substitute default values and instead call methods that require parameters to be explicitly specified. Чтобы преобразовать строку в верхний регистр с помощью соглашений о регистре текущего языка и региональных параметров, вызовите перегрузку метода ToUpper(CultureInfo) со значением CurrentCulture для своего параметра culture . To convert a string to uppercase by using the casing conventions of the current culture, call the ToUpper(CultureInfo) method overload with a value of CurrentCulture for its culture parameter.

mb_strtoupper — Приведение строки к верхнему регистру

(PHP 4 >= 4.3.0, PHP 5, PHP 7)

mb_strtoupper — Приведение строки к верхнему регистру

Описание

Возвращает строку str , буквенные символы в которой приведены к верхнему регистру.

Список параметров

Параметр encoding представляет собой символьную кодировку. Если он опущен, вместо него будет использовано значение внутренней кодировки.

Возвращаемые значения

str , буквы в которой приведены к верхнему регистру.

Юникод

За дополнительной информацией о свойствах Юникода обращайтесь в » http://www.unicode.org/unicode/reports/tr21/.

В отличие от strtoupper() , то что символ является буквой определяется на основании свойств символа Юникода. Таким образом на поведение функции не влияют региональные настройки системы, а также функция может преобразовывать символы, имеющие буквенные особенности, такие как а-умляут (ä).

Примеры

Пример #1 Пример использования mb_strtoupper()

Пример #2 Пример использования mb_strtoupper() с нелатинскими буквами

Смотрите также

  • mb_strtolower() — Приведение строки к нижнему регистру
  • mb_convert_case() — Производит смену регистра символов в строке
  • strtoupper() — Преобразует строку в верхний регистр

Что такое код strtoupper

Переехал я хостинг, перестала работать вот эта хрень. Почитал что надо ставить setlocale, везде стоит, однако не помогает. Кто нибудь может подсказать в чём проблема и как её устранить (может на хосте что отсутствует?) Спасибо

Kot Matroskin
Посмотреть профиль
Найти ещё сообщения от Kot Matroskin


05.04.2008, 12:52 #2

Sehnsucht У меня до этого setlocale(LC_ALL, array(‘ru_RU.CP1251’, ‘rus_RUS.1251’)); стоял. Попробывал ваш вариант, не помогло

Kot Matroskin добавил 05.04.2008 в 13:06
Вобщем у меня поиск имеется, если вводить запрос заглавными буквами, всё работает, а если ввести маленькими буквами, поиск не пашет.

strtoupper

(PHP 4, PHP 5, PHP 7)

strtoupper — Преобразует строку в верхний регистр

Описание

Возвращает строку string , в которой все буквенные символы переведены в верхний регистр.

Принадлежность того или иного символа к буквенным определяется с учетом текущей локали. Это означает, что, например, в используемой по умолчанию локали «C», символ ä не будет преобразован.

Список параметров

Возвращаемые значения

Возвращает строку в верхнем регистре.

Примеры

Пример #1 Пример использования strtoupper()

Примечания

Замечание: Эта функция безопасна для обработки данных в двоичной форме.

Смотрите также

  • strtolower() — Преобразует строку в нижний регистр
  • ucfirst() — Преобразует первый символ строки в верхний регистр
  • ucwords() — Преобразует в верхний регистр первый символ каждого слова в строке
  • mb_strtoupper() — Приведение строки к верхнему регистру

User Contributed Notes 16 notes

One might think that setting the correct locale would do the trick with for example german umlauts, but this is not the case. You have to use mb_strtoupper() instead:

echo strtoupper ( ‘Umlaute äöü in uppercase’ ); // outputs «UMLAUTE äöü IN UPPERCASE»
echo mb_strtoupper ( ‘Umlaute äöü in uppercase’ , ‘UTF-8’ ); // outputs «UMLAUTE ÄÖÜ IN UPPERCASE»

If you only need to extend the conversion by the characters of a certain language, it’s possible to control this using an environment variable to change the locale:

Simple function to change the case of your string and any accented html characters contained within it.

Inspired by fullUpper(), by silent at gmx dot li. just a little bit more atomic.

function convertCase ( $str , $case = ‘upper’ )
< //yours, courtesy of table4.com :)
switch( $case )
<
case «upper» :
default:
$str = strtoupper ( $str );
$pattern = ‘/&([A-Z])(UML|ACUTE|CIRC|TILDE|RING|’ ;
$pattern .= ‘ELIG|GRAVE|SLASH|HORN|CEDIL|TH);/e’ ;
$replace = «‘&’.’\\1′.strtolower(‘\\2′).’;'» ; //convert the important bit back to lower
break;

case «lower» :
$str = strtolower ( $str );
break;
>

$str = preg_replace ( $pattern , $replace , $str );
return $str ;
>
?>

Depending on what you are trying to achieve you would call like this:

//with entities.
$str = convertCase ( htmlentities ( $str , ENT_QUOTES , «ISO-8859-1» ));

It has been mentioned in a previous comment that all you need to do to let PHP’s strtoupper() do the conversion — instead of writing more or less complicated functions yourself — is to specify the locale in which you’re doing the case conversion:

( LC_CTYPE , «de_AT» ) ?>

It is important to note that setlocale() will silently fail if it can’t find the specified locale on your system, so *always* check its return value. Try different spellings: using «de_AT» as an example, there are various combinations that may or may not work for you: «de», «de_AT.utf8», «de_AT.iso-8859-1», «de_AT.latin1», «de_AT@euro», etc).

If you can’t find an appropriate locale setting, check your system configuration (locales are a system-wide setting, PHP gets them from the OS). On Windows, locales can be set from the Control Panel; on Linux it depends on your distribution. You can try «sudo dpkg-reconfigure locales» on Debian-based distros, or configure them manually. On Ubuntu Dapper, I had to copy entries over from /usr/share/i18n/SUPPORTED to /var/lib/locales/supported.d/local, then do the dpkg-reconfigure.

After you’re done, restart the web server.

That said, there are special cases where you want to do the conversion manually. In German, for example, the letter ‘ß’ (szlig) only exists as a lower-case character, and so doesn’t get converted by strtoupper. The convential way to express a ‘ß’ in an uppercase string is «SS». This function will take care of this exception (for Latin1 and most of Latin9, at least):

( «LATIN1_UC_CHARS» , «ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝ» );
define ( «LATIN1_LC_CHARS» , «àáâãäåæçèéêëìíîïðñòóôõöøùúûüý» );

function uc_latin1 ( $str ) <
$str = strtoupper ( strtr ( $str , LATIN1_LC_CHARS , LATIN1_UC_CHARS ));
return strtr ( $str , array( «ß» => «SS» ));
>

Проблемы работы функций strtoupper() и strtolower() с кириллицей

Проблемы при работе с кириллицей в PHP-скриптах функций strtoupper() и strtolower() возникают, когда неправильно определена текущая локаль (locale). Для правильного её определения Вам следует воспользоваться функцией setlocale() в самом начале вашего PHP-сценария, как в следующем примере:

В случае если используется многобайтовая кодировка, например UTF-8 следует использовать функции mb_strtolower() и mb_strtoupper().

Если у Вас возникли проблемы с устранением данной проблемы, Вы всегда можете обратиться в Службу технической поддержки хостинга.

ToUpper

Преобразует символы исходной строки в верхний регистр. Данная функция, помимо символов других алфавитов, корректно конвертирует кириллические символы (русские символы) в верхний регистр.

Примечание. Данную функцию можно использовать в случае если возникают проблемы с преобразованием кириллических символов стандартной PHP функцией strtoupper. Иногда это происходит на некоторых хостингах.

Параметры функции

05.04.2008, 12:59 #3
Параметр Описание С версии
text Исходная строка.
lang Идентификатор языка. 10.0.11

См. также

Примеры использования

Пользовательские комментарии

Мы будем рады, если разработчики добавят свои комментарии по практическому использованию методов системы.

Для этого нужно всего лишь авторизоваться на сайте

Но помните, что Пользовательские комментарии, несмотря на модерацию, не являются официальной документацией. Ответственность за их использование несет сам пользователь.

Также Пользовательские комментарии не являются местом для обсуждения функционала. По подобным вопросам обращайтесь на форумы.

Strtolower не работает в PHP: причины, исправление

Иногда при переходе на другой хостинг, или при установке новой версии PHP, перестает работать функция strtolower. Она начинает возвращать ту же строку, что и принимала, без приведения в нижний регистр. Это происходит из-за того, что неверно выставлена языковая локаль, и PHP не понимает, каким символам нижнего регистра должны соответствовать вводимые символы верхнего регистра. Проблема решается следующим образом.

Надо установить локаль. В windows это делается установкой переменной окружения LC_ALL в соответствующее значение (какое именно – описано ниже). Однако, если нет такой возможности, можно вызывать где-нибудь в главном или конфигурационном скрипте функцию установки локали в PHP setlocale (http://www.php.net/manual/en/function.setlocale.php). В руководстве PHP описано, какие значения и для каких целей можно устанавливать. Например,

Однако, мало установить значение. Нужно еще и проверить, что установилось:

так как функция setlocale возвращает false если не удалось установить локаль или имя локали, если удалось установить, это позволит убедиться в правильности выбранной настройки.

В вышеупомянутом разделе руководства PHP есть небольшая сноска для пользователей windows: http://msdn.microsoft.com/en-us/library/39cwe7zf(vs.71).aspx

из этого следует, что в windows правильным обозначением русской языковой локали является строка «rus». Таким образом, нужно использовать следующий простой вызов:

либо, как вариант:

Очевидно, данное решение применимо также если не работает функция strtoupper.

Невозможно обойти в стороне то бурление говн, которое происходит в интернете по поводу неработающей функции strtolower. Ниже приводятся примеры, которые ни в коем случае не следует использовать в качестве решения данной проблемы.

Редкостные извращенцы советуют использовать mb_strtolower (http://www.php.net/manual/en/function.mb-strtolower.php) вместо обычного strtolower, что в общем-то работать будет, но вам придется переписывать весь код. Кроме того, функция mb_strtolower более требовательна к ресурсам, поэтому не удивляйтесь, если ваш код начнет сильно тормозить. Для данного говно-метода расширение Multibyte String должно быть установлено, что также не на всех хостингах возможно. Используйте Multibyte String только по его прямому назначению, никогда не забивайте гвозди микроскопом.

Ну и напоследок, наиболее фееричный и ужасный способ перевода из верхнего регистра в нижний, который часто встречается в интернете:


Народ тупо и банально советует простым перебором, забив русский алфавит, заменять букву верхнего регистра на аналог в нижнем регистре. Это невообразимый пример говнокода, так никогда не надо делать.

Что такое код strtoupper

Python 3
Алгоритм приведения к верхнему регистру описан в параграфе 3.13 стандарта Unicode.

Python 2
Для строк с 8-битами на символ (юникод) работа метода зависит от текущей локали.

Для приведения символов строки к нижнему регистру используйте метод lower().

Для проверки того, содержит ли строка только символы в верхнем регистре используйте isupper().

Такое поведение возможно, если строка содержит только символы не поддерживающие приведение к регистру, либо Unicode-категория символа(ов) в результирующей строке не Lu (Letter, uppercase), а, например, Lt (Letter, titlecase).

Convert a String In C++ To Upper Case

How could one convert a string to upper case. The examples I have found from googling only have to deal with chars.

26 Answers 26

Boost string algorithms:

Short solution using C++11 and toupper().

Note: A couple of problems with the top solution:

21.5 Null-terminated sequence utilities

The contents of these headers shall be the same as the Standard C Library headers , , , , and [. ]

Which means that the cctype members may well be macros not suitable for direct consumption in standard algorithms.

Another problem with the same example is that it does not cast the argument or verify that this is non-negative; this is especially dangerous for systems where plain char is signed. (The reason being: if this is implemented as a macro it will probably use a lookup table and your argument indexes into that table. A negative index will give you UB.)

This problem is vectorizable with SIMD for the ASCII character set.

Speedup comparisons:

Preliminary testing with x86-64 gcc 5.2 -O3 -march=native on a Core2Duo (Merom). The same string of 120 characters (mixed lowercase and non-lowercase ASCII), converted in a loop 40M times (with no cross-file inlining, so the compiler can’t optimize away or hoist any of it out of the loop). Same source and dest buffers, so no malloc overhead or memory/cache effects: data is hot in L1 cache the whole time, and we’re purely CPU-bound.

boost::to_upper_copy () : 198.0s. Yes, Boost 1.58 on Ubuntu 15.10 is really this slow. I profiled and single-stepped the asm in a debugger, and it’s really, really bad: there’s a dynamic_cast of a locale variable happening per character. (dynamic_cast takes multiple calls to strcmp). This happens with LANG=C and with LANG=en_CA.UTF-8 .

I didn’t test using a RangeT other than std::string. Maybe the other form of to_upper_copy optimizes better, but I think it will always new / malloc space for the copy, so it’s harder to test. Maybe something I did differs from a normal use-case, and maybe normally stopped g++ can hoist the locale setup stuff out of the per-character loop. My loop reading from a std::string and writing to a char dstbuf[4096] makes sense for testing.

loop calling glibc toupper : 6.67s (not checking the int result for potential multi-byte UTF-8, though. This matters for Turkish.)

  • ASCII-only loop: 8.79s (my baseline version for the results below.) Apparently a table-lookup is faster than a cmov , with the table hot in L1 anyway.
  • ASCII-only auto-vectorized: 2.51s. (120 chars is half way between worst case and best case, see below)
  • ASCII-only manually vectorized: 1.35s
  • I was shocked that Boost is an order of magnitude slower than the other options. I double-checked that I had -O3 enabled, and even single-stepped the asm to see what it was doing. It’s almost exactly the same speed with clang++ 3.8. It has huge overhead inside the per-character loop. The perf record / report result (for the cycles perf event) is:

    Autovectorization

    Gcc and clang will only auto-vectorize loops when the iteration count is known ahead of the loop. (i.e. search loops like plain-C implementation of strlen won’t autovectorize.)

    Thus, for strings small enough to fit in cache, we get a significant speedup for strings

    128 chars long from doing strlen first. This won’t be necessary for explicit-length strings (like C++ std::string ).

    Any decent libc will have an efficient strlen that’s much faster than looping a byte at a time, so separate vectorized strlen and toupper loops are faster.

    Baseline: a loop that checks for a terminating 0 on the fly.

    Times for 40M iterations, on a Core2 (Merom) 2.4GHz. gcc 5.2 -O3 -march=native . (Ubuntu 15.10). dst != src (so we make a copy), but they don’t overlap (and aren’t nearby). Both are aligned.

    • 15 char string: baseline: 1.08s. autovec: 1.34s
    • 16 char string: baseline: 1.16s. autovec: 1.52s
    • 127 char string: baseline: 8.91s. autovec: 2.98s // non-vector cleanup has 15 chars to process
    • 128 char string: baseline: 9.00s. autovec: 2.06s
    • 129 char string: baseline: 9.04s. autovec: 2.07s // non-vector cleanup has 1 char to process

    Some results are a bit different with clang.

    The microbenchmark loop that calls the function is in a separate file. Otherwise it inlines and strlen() gets hoisted out of the loop, and it runs dramatically faster, esp. for 16 char strings (0.187s).

    This has the major advantage that gcc can auto-vectorize it for any architecture, but the major disadvantage that it’s slower for the usually-common case of small strings.

    So there are big speedups, but compiler auto-vectorization doesn’t make great code, esp. for cleanup of the last up-to-15 characters.

    Manual vectorization with SSE intrinsics:

    Based on my case-flip function that inverts the case of every alphabetic character. It takes advantage of the «unsigned compare trick», where you can do low with a single unsigned comparison by range shifting, so that any value less than low wraps to a value that’s greater than high . (This works if low and high aren’t too far apart.)

    SSE only has a signed compare-greater, but we can still use the «unsigned compare» trick by range-shifting to the bottom of the signed range: Subtract ‘a’+128, so the alphabetic characters range from -128 to -128+25 (-128+’z’-‘a’)

    Note that adding 128 and subtracting 128 are the same thing for 8bit integers. There’s nowhere for the carry to go, so it’s just xor (carryless add), flipping the high bit.

    Given this function that works for one vector, we can call it in a loop to process a whole string. Since we’re already targeting SSE2, we can do a vectorized end-of-string check at the same time.

    We can also do much better for the «cleanup» of the last up-to-15 bytes left over after doing vectors of 16B: upper-casing is idempotent, so re-processing some input bytes is fine. We do an unaligned load of the last 16B of the source, and store it into the dest buffer overlapping the last 16B store from the loop.

    The only time this doesn’t work is when the whole string is under 16B: Even when dst=src , non-atomic read-modify-write is not the same thing as not touching some bytes at all, and can break multithreaded code.

    We have a scalar loop for that, and also to get src aligned. Since we don’t know where the terminating 0 will be, an unaligned load from src might cross into the next page and segfault. If we need any bytes in an aligned 16B chunk, it’s always safe to load the whole aligned 16B chunk.

    Times for 40M iterations, on a Core2 (Merom) 2.4GHz. gcc 5.2 -O3 -march=native . (Ubuntu 15.10). dst != src (so we make a copy), but they don’t overlap (and aren’t nearby). Both are aligned.

    • 15 char string: baseline: 1.08s. autovec: 1.34s. manual: 1.29s
    • 16 char string: baseline: 1.16s. autovec: 1.52s. manual: 0.335s
    • 31 char string: manual: 0.479s
    • 127 char string: baseline: 8.91s. autovec: 2.98s. manual: 0.925s
    • 128 char string: baseline: 9.00s. autovec: 2.06s. manual: 0.931s
    • 129 char string: baseline: 9.04s. autovec: 2.07s. manual: 1.02s

    (Actually timed with _mm_store in the loop, not _mm_storeu , because storeu is slower on Merom even when the address is aligned. It’s fine on Nehalem and later. I’ve also left the code as-is for now, instead of fixing the failure to copy the terminating 0 in some cases, because I don’t want to re-time everything.)

    So for short strings longer than 16B, this is dramatically faster than auto-vectorized. Lengths one-less-than-a-vector-width don’t present a problem. They might be a problem when operating in-place, because of a store-forwarding stall. (But note that it’s still fine to process our own output, rather than the original input, because toupper is idempotent).

    There’s a lot of scope for tuning this for different use-cases, depending on what the surrounding code wants, and the target microarchitecture. Getting the compiler to emit nice code for the cleanup portion is tricky. Using ffs(3) (which compiles to bsf or tzcnt on x86) seems to be good, but obviously that bit needs a re-think since I noticed a bug after writing up most of this answer (see the FIXME comments).

    Vector speedups for even smaller strings can be obtained with movq or movd loads/stores. Customize as necessary for your use-case.

    We can detect when our vector has any bytes with the high bit set, and in that case fall back to a scalar utf-8-aware loop for that vector. The dst point can advance by a different amount than the src pointer, but once we get back to an aligned src pointer, we’ll still just do unaligned vector stores to dst .

    For text that’s UTF-8, but mostly consists of the ASCII subset of UTF-8, this can be good: high performance in the common case with correct behaviour in all cases. When there’s a lot of non-ASCII, it will probably be worse than staying in the scalar UTF-8 aware loop all the time, though.

    Making English faster at the expense of other languages is not a future-proof decision if the downside is significant.

    Locale-aware:

    In the Turkish locale ( tr_TR ), the correct result from toupper(‘i’) is ‘İ’ (U0130), not ‘I’ (plain ASCII). See Martin Bonner’s comments on a question about tolower() being slow on Windows.

    We can also check for an exception-list and fallback to scalar there, like for multi-byte UTF8 input characters.

    With this much complexity, SSE4.2 PCMPISTRM or something might be able to do a lot of our checks in one go.

    Илон Маск рекомендует:  Положение фона
    Понравилась статья? Поделиться с друзьями:
    Кодинг, CSS и SQL