Pull to refresh

Comments 99

tl;dr: регулярки в сишном движке быстрее любого кода, написанного на интерпретируемом недоязыке.

Теперь я могу ответить на вопрос: как же быстрее всего обнаружить гласную в строке? Похоже, при помощи битовой карты на C.

Скорее всего, даже не биткарта, а какой-нибудь трюк с avx512, чтобы сканировать 64 байта за такт. SIMDJSON это для парсинга JSON использует.

Может регулярку сделать Case Insensitive и создавать 1 раз вне функции? Или питон кеширует?

Питон кеширует)

но тут нюанс что это в строке(тоесть варианта 2 учесть все случаи regex, или писать самому поиск чото такое - я для себя так понял), перемена местами логически выглядит как пока есть строка сравнение с буквы с гласной, и далее конечная проверка на вхождение в строку типо что-то такое - (так понял, может ошибаюсь), тоесть это ближайшая опора к кмп

еще нюанс может быть при 1000000 символов, строк может быть 100 000

Алгоритм_Кнута_—_Морриса_—_Пратта

дальше пойдёт(или не пойдёт, ну я задавался таким вопросом )) сравнение что лучше хэш, лист, дабл лист, или дерево с авто сортировкой) или ничего ну тоесть результаты делаются при проходе (что регекс, что выбранный), ну потомучто конверсия при прогонке поидее тоже ест производительность наверно(регекс кароче более требователен к тонкой настройке, своё разбитие может быть просто читаемее - понятнее)

тема интересная, спасибо, тоже столкнулся

п.с. поиск гласного частный случай поиска кмп вобщем-то ну или чего-то похожего по поиску слов, например какая-нибудь маска битовая слова или буквы(тоесть приводящая к симд наверно косвенно)

пойду от обратного, только что придумал, если имеем полу кмп поиск первого вхождения), то если иметь угадыватель - разбиватель строк по принципу по 1 вхождению, то полу кмп будет еффективнее)(хотя вроде спорно, но интересно), но тут на букву и слово будут разные угадыватели-разбиватели)

Naïve, Moët, половина немецкого языка и три четверти французского и испанского смотрят на список гласных с недоумением.

Naïve и Moët не самые удачные примеры. Алгоритм сработает на “a” и “o”.

Но есть простое английское слово pâté. И его можно записать четырьмя кодепоинтами (второй — ʟᴀᴛɪɴ ꜱᴍᴀʟʟ ʟᴇᴛᴛᴇʀ ᴀ ᴡɪᴛʜ ᴄɪʀᴄᴜᴍꜰʟᴇx, U+00E2, четвёртый — ʟᴀᴛɪɴ ꜱᴍᴀʟʟ ʟᴇᴛᴛᴇʀ ᴇ ᴡɪᴛʜ ᴀᴄᴜᴛᴇ, U+00E9). И на нём функция скажет: «Бдзынь!», а мы скажем: «Вот то-то же».

«Naïve» — английское слово, записанное по правилам английского языка (диерезис ломает дифтонг, иначе читалось бы «найв»). Его можно записать пятью кодпоинтами в NFC (Normalization Form Canonical Composition).

Слово «pâté» — заимствование из французского и пишется по правилам французского языка, как практически всё, что заимствуется в английский из языков с тем же алфавитом.

Зачем, интересно, вам потребовалась фраза про «неудачный пример»?

Так и naïve точно такое же заимствование из французского, написанное по-французски. Naive тоже правильно.

Откуда вы все такие полиглоты берётесь-то, а?

Французское слово — «naïf», и в английский именно оно напрямую заимствовано не было.

Как я написал выше, две точки в английском «naïve» — это диерезис. Приличные английские издания до сих пор «coöperation» с тремой пишут — тоже заимствование?

Naive тоже правильно.

Кому и кобыла невеста.

coöperation» с тремой пишут — тоже заимствование?

Вы сейчас серьезно спрашиваете, является ли слово cooperation в английском языке заимствованием? Ваша квалификация ясна.

Кому и кобыла невеста

Напишите это в издательства словарей Cambridge, Merriam-Webster, Collins.

Французское слово — «naïf», и в английский именно оно напрямую заимствовано не было.

В мужском роде. А в женском - naïve, прямо по вашей же ссылке: De la poésie naïve et sentimentale.

Зачем, интересно, вам потребовалась фраза про «неудачный пример»?

Повторяю:

Алгоритм сработает на “a” и “o”

P.S. Первоначально мой комментарий содержал не одну, а две причины считать это неудачными примерами. От одной я отказался сразу же, отредактировав комментарий через минуту. Видимо, Хабр успел отправить уведомление с первоначальным текстом комментария.

От второй причины («алгоритм сработает на “a” и “o”») я не отказываюсь.

Наивно ожидал здесь увидеть решение для всего юникода )

Там всё просто: надо распарсить последнюю спецификацию консорциума, выкусить оттуда гласные… Ах да, консорциум же не озаботился добавить ни в названия, ни в мету информацию гласная/согласная :)

Консорциум не в курсе, что такое гласная/согласная
Консорциум не в курсе, что такое гласная/согласная

Так что нет, Хрюша сегодня не придёт.

Ах да, консорциум же не озаботился добавить ни в названия, ни в мету информацию гласная/согласная

«Любая, даже самая сложная, проблема обязательно имеет простое, легкое для понимания, неправильное решение.»

Возьмём, для примера, простую букву «Ъ». Ну явно же она не гласная, это и дураку понятно. Потом идём в Википедию и, упс:

в болгарском языке буква ъ (болг. ер голям) имеет собственную своеобразную фонему, под ударением реализующуюся как неогублённый гласный звук заднего ряда средне-верхнего подъёма.

Что в метаинформацию для этой кириллической буквы писать будем?

С капитализацией i для турецкого они же справились как-то.

Хреново справились, цензурно выражаясь. Нагородили костылей в турецкой локали.

В спецификациях консорциума нет понятия «локаль».

Если кому интересно - есть такая библиотека ICU, с помощью нее можно проверять гласность на уровне всего юникода.

Таких библиотек полно́, проблема в том, что они все до единой созданы вручную.

А как иначе-то? Сама должна появиться? )

В спецификации консорциума есть даже такие мелочи, как правильный casing (чтобы в турецком "istanbul".to_upper превращался в "İstanbul").

Грамотно спроектированные языки — парсят эту спецификацию. Но с гласными/согласными — это не проходит, приходится размечать руками.

Zs

будет ли в Н слоях спейс одинаковый? (не получится так что он где-то другой код)

Деление звуков на гласные/согласные существует не во всех языках. В некоторых такое разделение просто бессмысленно...

Деление звуков (подчеркиваю - звуков) на гласные и согласные так или иначе есть во всех языках согласно международному фонетическому алфавиту, а вот в плане письменности - да, бывает бессмысленно, но в таком случае символ просто не гласная и не согласная. Кстати гласным символ может быть или не быть в зависимости от диакритических знаков в некоторых языках. Так что все очень неоднозначно, всем надо переходить на фонетический алфавит - а то развели тут зоопарк понимаешь )

Абстрактное фонетическое дерево!

  1. Ну в статье идёт речь именно о письменности, а не о фонетике, поскольку мы имеем здесь дело не с языками, а с изображением текстов.

  2. Не всякий письменный язык - фонетический. Насчёт перехода на фонетическую письменность: а вы когда-нибудь задавались вопросом, почему этого не происходит? Это же не просто так всё... Я, когда начинал изучать иврит, тоже думал - "ну, на кой это всё?" А сейчас вот повзрослел, особенно, когда про китайский кое-что понял... Кстати, реформа русского языка после революции очень здорово порубила его базовые смыслы, превратив живой, довольно, правда, сложный, но построенный на определенной логике и имеющий свою историю язык в упрощённый набор звуков...

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

  2. Не происходит потому, что всем не угодишь, мне например не нравится фонетический алфавит на основе латиницы. Живой язык, на то и живой, чтобы эволюционировать. Иногда нужно избавляться и от архаики, это полезно, вот например зачем нам Ш и Щ? Ведь Щ - это мягкая Ш, там и пресловутые ЧА ЩА и другие правила нормализовать можно, да и нормальное место на клавиатуре для Ё (кстати гораздо более нужной в качестве отдельного символа) нашлось бы сразу. Но это конечно имхо, имеем все равно то что имеем.

самое классное это получить все ключи - то для чего и создано программирование например из слов 你好 ведь их можно сравнивать и как просто конечное слово и как 2 слова, и как составные ключи. другой пример не пришел мне, ну или как в Корейском языке падчим найти все составные падчима, собственно это то решение которое в дополнении для ввода такого рода символов, но наоборот. Типо дано конечное состояние, его надо проанализировать и вывести все ключи.

если посмотреть на Хирагану-Катакану, то там тоже есть мягкость и твёрдость

Шявель?

Немцы же как-то справляются: Tschyawell.

После Chruschtschow им уже все равно.

Немцу хорошо, что Хрущёв любил борщ, но плохо, что он не был великим чучхе.

Tschyawell

Что это?
Звук, похожий на русское «Й» в немецком передаётся буквой «J». Даже не учившие немецкий наверняка знают восклицание «Ja-ja!».

Группа «Tsch» обозначает звук «Ч». Далеко ходить не надо, «Deutsch», «Дойч» — «немецкий».

А щавель это «Sauerampfer».

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

Нет. Если посмотреть на фонетическую запись, сразу видно какое это убожество. Как геометрическую задачу решать алгеброй.

Тащить многовековой давности легаси в правилах орфографии не очень осмысленно. Разницы между "ять" и "е" русскоговорящие люди не слышали уже в 18 веке, не говоря уж про 20-й, ну и зачем было учить наизусть список слов, где положено писать "ять"? "Ер" (твердый знак) в конце слова когда-то был гласным - потому что в древнерусском языке существительное не могло заканчиваться согласным звуком, вот он и выполнял роль такой фиктивной гласной, соответствуя специфическому слабому е. Но такого произношения, наверное, уже при Борисе Годунове не существовало.

Проблема в том, что во всём ищется логический смысл с желанием всё упростить. Культура - она не про упрощение. Это в математике нужно всё сокращать с целью упрощения. Но язык - это не математика. Язык - это не просто передача информации с помощью звуков. Это огромный пласт культуры, в том числе и визуальной... Рассуждая о культуре и истории с точки зрения логики, можно выбросить, в итоге, всё, что отличает человека от животного - а чего там - пить-есть-размножаться - какая там Культура, История, Мысль? А животному зачем язык? Можно обойтись рычанием, воем, потявкиванием - десяток-другой сигналов и всё. Вот к этому и ведёт Великое Логичное Упрощение.

Сумбурно, но нет у меня ни желания ни сил переубеждать великих Логиков...

Заглавные буквы использовал намеренно, для усиления, так сказать... Кстати, в иврите нет заглавных букв, зато есть, так сказать "конечные" - ну, не было в языке когда-то давно пробелов между словами (а, кстати, на древнеславянские тексты посмотрите). Тоже архаизм...

Недавно совсем узнал:

Аз буки веди - я знаю буквы,

Глаголь добро есть - слово - это добро (достояние)

Живѣте зело и иже како люди - живите усердно, как подобает людям...

Вот в нашей абэвэгэдэйке кто про это сейчас помнит?

Ну я помню :) А толку?

А толк в том и есть, что вы - помните! )

Всё-таки расшифрую :). Личность человека - это то, что он помнит. Когда память начинает разрушаться - это такие заболевания есть, в старости особенно :) - личность разрушается...

Молодцы древние греки! Сразу так алфавит придумали, что он на древнерусском стал какой-то текст (нет!).

Можете эту фоменковщину спокойно забыть.

Какую еще фоменковщину? Вы отрицаете названия букв кириллицы?

Нет, я не отрицаю названия букв кириллицы. Я (и даже не я, а научный мир) отрицаю то, что эти названия несут какой-то сакральный смысл (и, как мне кажется, довольно ясно об этом написал).

Да в принципе и в исходном комметарии понятно, что речь не о названиях букв, а о тексте, который они якобы образуют.

Какой еще нафиг сакральный смысл? Вы там белены объелись? Это названия букв на старославянском, выбранные так, чтобы их было проще запомнить.

«Аз» — это буквально «я», «буки» — буквы, «веде» — глагол знать/изучать в первом лице.

Когда пишут названия букв на старославянском, то их просто пишут - аз, буки, веди, глагол, добро и тд. А когда их вот так разделяют на фразы, да еще и с комметариями, как здесь

Аз буки веди - я знаю буквы,

Глаголь добро есть - слово - это добро (достояние)

Живѣте зело и иже како люди - живите усердно, как подобает людям...

то это явный маркер, что речь идет вот об этой фоменковщине: Русская Азбука – Послание к славянам

А при чем тут слово "сакральный"? При чём тут какие-то "послания к славянам"? Где вы его увидели? Построить алфавит таким образом, чтобы последовательность названий букв складывалась в какой-нибудь осмысленный текст - это вполне логичный прием для лучшего запоминания. Зачем накручивать здесь конспирологические выводы? Если названия букв имеют какой-то смысл - каким образом устанавливать порядок этих букв? Почему не использовать осмысленный текст? Что в этом криминального?

У вас в детстве кубики со словами для каждой буквы были?

Вот блин, сразу "фоменковщина", понимаешь, ярлыки навешивать кинулись - ещё заявление в партийные органы напишите. Для начала, со своими тараканами в голове разберитесь...

Мне, главное, нравится это постоянное употребление слова "просто" - вот, просто берут и пишут. Вы когда-нибудь пытались для какого-то народа алфавит придумать? Полагаете это очень просто?

Вам известно, почему в этом алфавите буквы именно в таком порядке? И почему там раньше было больше букв? Потому что этот алфавит создан на основе греческого алфавита. Вроде бы общеизвестный факт. По-вашему, древние греки специально так составили свои буквы, чтобы они потом через сотни лет образовали текст на старославянском языке? Это не алфавит построен так, чтобы последовательность названий букв складывалась в текст, а названия букв придуманы так, чтобы получалось более-менее что-то осмысленное.

 Для начала, со своими тараканами в голове разберитесь...

Изучите сначала вопрос хоть немного.

Конечно. Но названия букв вроде придумал не Фоменко.

А речь и не о названиях букв, а о тексте, который они якобы образуют.

Аз буки веди - я знаю буквы,

Глаголь добро есть - слово - это добро (достояние)

Живѣте зело и иже како люди - живите усердно, как подобает людям.

Там между "зело" и "и" была еще одна буква. И между "иже" и "как" тоже была. Да и вообще буквы "и" и "иже" стояли в другом порядке - не "и, иже", а "иже, и". Как-то не получается осмысленный текст. Ну и слово "глаголь" означает все же не "слово", так что вся эта красивая теория рушится уже на первых буквах.

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

Что забавно, греки, как раз, сильно по поводу своего алфавита не заморачивались - взяли тот же финикийский и даже названия букв не поменяли (может, добавили пару штук). Но у них история другая... А европейцы - взяли латиницу и умляутов поналепили с долготами и прочими акцентами...

Насколько я понимаю, трансформация финикийский→греческий была примерно такая же, как арамейский→иврит. Они некоторое время сосуществовали, поэтому греческий и иврит следует считать форками :))

Молодцы древние греки! Сразу так алфавит придумали, что он на древнерусском стал какой-то текст (нет!).

Вот эта ваша фраза говорит о том, что вы вообще не понимаете, о чем пишете. Греки свой алфавит заимствовали у финикийцев (видимо - финикийский был тогда своего рода языком межнационального общения в том регионе). У греков не было своих Кирилла и Мефодия. Связь кириллицы и греческого алфавита существует, но названия кириллических букв взяты не из греческого, поэтому он может быть текстом просто потому, что Кирилл и Мефодий специально так подобрали слова на славянском языке для лучшего запоминания. Так что и греки не молодцы и текст вполне может быть осмысленным. Ну, если вы не знаете: "Алеф" - это, скорее всего, "бык", "Бет" - "дом", "Гимель" - скорее всего, "верблюд", "далет" - дверь. Ну и т.д... Тоже не "абэгэдэ..."

У алефа есть прям прямой предок в древнеегипетской иероглифике, бык. И так далее по списку.

Самая устойчивая буква, наверное, по форме :). Даже א в рукописном виде можно узнать.

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

это же зависит от ввода, загруженного языка, тоесть это загрузили язык, храним строку определенного веса, в статье рассматривается просто работа со строкой, тоесть придётся делать больше проверок на соответствие шрифта к набору на ПК(или не делать, но размер строки будет влиять на то какие строки и какое количество символов рисуется, например Китайский 1000 000 символов и 100 000 строк это будет не такой размер как с аски), на дефолтовом уровне проще поддерживать решение с аски, а далее уже смотреть с языками, потомучто решение с Юникодом в купе с отрисовкой будет сьедать ресурс

и придём в итоге к локализации и прописи локали в локализации, если писать свой движок на юникодах(из точек через ttf)

на аски проще если это консоль и/или фреймворк уже имеет в себе все эти проверки

например свинг поидее имеет эти проверки, соотв я просто работаю со строкой, а как она будет рисоваться пока не волнует пока нет такого вопроса

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

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

чем дальше индекс тем меньше или нулевая вероятность встретить конкретную гласную, если до этого индекса были все согласные

там обычно чаще суть в том чтобы знать где буква-слово в исходном тексте, соотв нужны они все

Скрытый текст
class kvlist {
    private Integer k;
    private String v;
    public kvlist(int ka,String ve){
        this.k=ka;
        this.v=ve;
    }
    public Integer getKa(){
        return k;
    }
    public String getVe(){
        return v;
    }
}


public class example {
    public static void main(String[] args) {
        String text = "你好 早上好 你好 晚上好 你好吗? 你好 谢谢 你好 不客气 你好 你好 请 你好 对不起 没关系 你好 我叫 你好 再见 你好 我";


        String[] parts = text.split(" ");//\n
        
    	String search = "你好";

        List<kvlist> sortedByKeyMap = new ArrayList<>();
        int searchStartIndex = 0;

        for (String word : parts) {
            String[] parts1 = word.split("(?U)(?<=\\s)(?=\\S)|(?<=\\S)(?=\\s)|(?<=\\w)(?=\\W)|(?<=\\W)");//
            for(String r:parts1){
                int indexInText = text.indexOf(r, searchStartIndex);
        		if (indexInText >= 0) {
        		    sortedByKeyMap.add(new kvlist(indexInText,new String(r)));
        		    searchStartIndex = indexInText + r.length();
        		}

            }

        }

        for (kvlist entry: sortedByKeyMap) {
    	    if(entry.getVe().equals(search)){
        		System.out.println(entry.getKa()+" "+entry.getVe());
    	    }
        }
    }
}

еще можно попробовать поиграться с масками, там буквы гласные в таблице в ряд стоят...

Нет, в ASCII буквы идут по алфавиту. Но удачно получилось, что все гласные на нечётных позициях

Так что самый младший бит всегда 1. Дальше можно смотреть на пятый с конца бит, который для всех кроме U равен 0.

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

я погуглил, максимальное колличество согласных в начале 3 штуки. значит 32 битная маска покроет все случаи. маски нужно две штуки, и накладывать сразу на начало слова, если символов от 3. учитывая 0 в конце. если символов меньше чем 3, то 16 битные маски. если меньшн чем 1 то гласных точно нет.

я погуглил, максимальное колличество согласных в начале 3 штуки

Извините, если не совсем правильно Вас понял, но про что данная сентенция? Если про количество согласных в начале слова, то не только сакраментальное "взбзднуть", но и банальное "всплакнуть" нарушают данное правило (не забываем про финальное буквосочетание в слове "длинношеее"). Или Вы имели в виду какой-то конкретный язык с конкретным алфавитом? Мне в этом плане арабская письменность нравится - там всего одна "гласная" буква =)

в условной задаче, речь об английском языке

В итоге получается 3 маски

if ((index & 0b_1101_0111) == 0b_0100_0001 || // A I
	(index & 0b_1100_1111) == 0b_0100_0101 || // E U
	(index & 0b_1101_1111) == 0b_0100_1111) // O
{
	Debug.LogError(ch);
}

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

думаю такой код хорошо будет работать на совремнных процах. там оптимизации такие же как и у clamp и min и max. т.е. короткие независимые ветки, исполняемые одновременно и потом выкидывание ненужных результатов без сброса конвеера.

Как минимум на х86 вы ничего не выиграете. Можно побороть большие/маленькие буквы сбросом "case" бита, а потом проверять xor cо значениями сохраненными в байтовых регистрах - на английский должно хватить. Это даст существенный прирост.

Проверяемый текст можно загружать в ммх регистр или 64 бит регистр и постепенно сдвигать вправо проверяя младший байт, насколько я помню можно загрузить левые в памяти байты в младшие регистры. Жаль что в Питоне нельзя ассемблерных вставки.

Python уже забыл, поэтому попросил qwen2.5-coder-32b-instruct-q4_k_m
написать так, как представляю максимально быстрый способ:

"Напиши на python функцию any_gen(s), которая возвращает true,
если в строке s есть гласные буквы: aeiouAEIOU.
При этом для скорости вначале создай массив, в котором в элементе с
номером равным коду гласной буквы стоит true и затем
в цикле по строке s определять гласную букву по этому массиву."

LLM эти путанные объяснения правильно поняла и написала
и с русскими комментариями и всё объяснила и тесты написала и всё работает.
Это потрясающе!

скорость упадёт как только добавится к этой задаче "все вхождения сделать все засечки за 1 проход, учитывая все открывания закрывания и весь синтаксис", там будет выбор регекс не 1 проход или не регекс 1 проход с проверками, при этом на больших данных регекс будет поидее не маленький уже, невозможно проверять только гласные(гласные это частный случай)

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

и ИИ будет предлагать именно из-за страха потери символа - эвристики, будет всё делать на регеспе и за несколько проходов

Да, результаты LLM впечатляют. Такие задачи делает на ура.
Я хочу начат pet-проект с бэком на питоне и фронтом на vue. С питоном я дружу хорошо, а вот во фронтовой части опыта нет, не знаю ни vue, ни js. Попробовал использовать для фронтовой части LLM. В общем, вполне можно работать. Прошу написать компонент, ставлю задачу. На vue делает достаточно хорошо. Потом я вычитываю, проверяю. Что не понятно, спрашиваю. Например, "а вот что означает эта конструкция на js?". LLM подробно объясняет. Что-то немного переделываю. Иногда бывают косяки - в основном, из-за нечеткой постановки. Но вполне можно работать и делать фронт на языке, которого я не знаю) Но опыт разработки должен быть обязательно. Условная "домохозяйка" проект не сделает.

В начале просил LLM сделать полностью заготовку проекта (бэк+фронт). Она не справилась. Это сложно. А вот компоненты на vue клепает очень годно)

Почему регэксп в питоне быстрее всего другого написанного на питоне? Просто потому что он (в отличии от всего остального) написан на C.

Возьмите C или что-то посвежее, компилируемое в машинный код и там регулярки уже не такие быстрые по факту даже пред-компилированные.

Для ASCII быстрее всего будет завести массив a[255] где каждый элемент 1, если код соответствует гласной и 0 если нет. А дальше просто цикл

Не факт. Массив размером 255 — относительно большой. Если у процессора кеш-линия длиной 256 байт и больше, то к нему требуется только выравнивание, чтобы массив не делился на 2 кеш-линии. Но у большинства процессоров кеш-линия короче 256 байт, что подразумевает априори 2/4/8 запросов в память по сравнению с тем же способом с бит-масками, оперирующими с регистрами и immediate при соответствующем соглашении о вызовах (вне рамок питона). Но это ничего не доказывает само по себе: правда в benchmark'ах. Если вам интересно, можете проверить

Y чего нигде нет

Короче зависит от входных данных. Если например гласная редкая, то можно завести массив целых чисел с 26 элементами, использовать очередную букву из строки как индекс элемента массива, и добавлять к элементу 1. А уже в самом конце проверить, что там по индексам 1 5 9 15 21.. это избавит от проверок но зависит от частоты гласных, входных данных

мне кажется для решения нужно брать статистику по появлению гласных в английском тексте и условия выстраивать по нисходящей. там где это можно - проверять по битовой маске.

а вообще можно в 100% случаев просто возращать true, так как в английском тексте нет слов без гласных ) (во всяком случае я такие не вспомнил)

ИИ:

Да, в английском языке существуют слова, состоящие исключительно из согласных букв. Примеры таких слов включают:

  • hmm — междометие, выражающее сомнение или размышление ("хмм").

  • psst — звукоподражательное слово, используемое для привлечения внимания ("псст").

  • shhh — звукоподражательное слово, означающее призыв к тишине ("ш-ш-ш").

  • brrr — звукоподражательное слово, выражающее холод ("бр-р-р").

Эти слова часто используются в разговорной речи и письменной форме для передачи звуков или эмоций.

Что-то у вашего ИИ словарный запас пффф. «Звукоподражательное слово» называется в русском языке «ономатопея».

у меня нет ИИ, это общедоступный бесплатный GigaChat, можете написать им.

Хм. Если посмотреть на скорость в символах в секунду, то самый быстрый вариант оригинала статьи в его замерах ищет со скоростью порядка 100к симв/сек. Про улучшенный вариант Kranar/a_e_k пишут, что они "быстрее в 10 раз". Миллион символов строк в секунду (если я нигде множитель не пропустил).
Это ж, блин, соревнование улиток какое-то. Скорее всего почти всё время уходит на интерпретатор и движок Python, потому что на C/C++/Rust/C#/Java я бы ожидал скорости порядка 100М-1G симв/сек на реализациях без SIMD и 1-10G для SIMD.

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

Даже если предположить что формат входных данных это 8-битовый набор символов ASCII то тема не до конца раскрыта. Нужно изучить положение битов влияющих на требуемый признак символа и подумать можно ли как то более быстро определять гласный он или нет.

Можно задаться вопрос о смене формата данных для более быстрого получения признаков символа изменив кодировку. Но это ещё более широкая задача. Это похоже на построение индексов в БД.

Тем не менее статья интересная.

Не хватает:
1. Варианта на numpy
2. Варианта с numba
3. Варианта с torch на cpu
4. Варианта с torch на gpu
Возможно, вечером сделаю. Если никто не опередит))

Попробовал 1 и 2. Лидера побить не могут. Основная причина - эти варианты не работают с нативными строками питон, и преобразование съедает весь выигрыш распараллеливания.
- Преобразование в массивы numpy, даже np.frombuffer(b"aeiouAEIOU", dtype=np.uint8) - долго
- Нумба умеет работать сразу с байтовыми массивами. Но с ограничениями, она не может распараллелить операции с ними (
- Ну а учитывая предыдущее, torch пробовать смысла нет

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

В английском употребление артиклей a/an зависит от первого звука при произношении, а не буквы: a man, a unicorn/an apple, an honest.

Кстати, результатами теста не удивляен. Изначально бы ставил на решение от a_e_k . Операция in в питоне наверняка в итоге сводится на машинном коде в инстукцию ассемблера rep scasb. Вряд ли есть что либо более эффективное для одного ядра. Потери тут только в том, что идет отдельный вызов через медленный интерпретатор для каждой гласной.


Но... все предложенные мной варианты в комментарии выше могут использовать несколько ядер cpu или gpu, поэтому у них есть шанс вырваться вперед на больших строках. Вопрос лишь в стоимости накладных расходов при подготовки данных.

стоимость просто замерить и увидеть, надо открыть vulkan_core.h и запустить скан гласных

А еще есть frozenset

Но не думаю, что он будет сильно быстрее обычного ...

Какие-то не модные решения. Надо было обучить нейросеть-классификатор. Берем датасет строк с гласными, берем датасет без гласных... обучаем ночь на нескольких 4090...

самого быстрого способа нахождения гласной в строке - ЗДЕСЬ НЕТ! самый быстрый способ это использование массива, где индексом будет код буквы(ну или его смещение относительно первой буквы алфавита), а элементами логические значения, на месте гласных истина, согласных ложь.

Или Set вместо массива (чуть поменьше по памяти).

В принципе, регулярка из статьи как раз и скомпилировалась в нечто подобное. Этот вариант потому и самый быстрый оказался (а не только потому, что на С).

вопрос в том как реализован сет? можно просто список!!! я такие реализации встречал. Можно хеш-таблица, это будет быстро, но медленнее чем массив. но экономичнее по памяти. Или сет через бинарные деревья. но опять таки это всё медленнее. я предложил вариант, с максимальным использованием памяти, но максимальным по производительности, т.е с минимальной вычислительной нагрузкой.

А в чем смысл продолжения поиска до конца строки после первой встретившейся гласной?

Первую половину удивлялся, почему идея нахождения быстрого алгоритма была запущена на самом неочевидном для проверки скоростей языке, а во второй половине выяснилось, что самый быстрый алгоритм на питоне - это алгоритм в котором минимум питона. И почему же я не удивлён

Какие бенчмарки будут, если использовать вместо import re библиотеку import regex?

Sign up to leave a comment.

Information

Website
ruvds.com
Registered
Founded
Employees
11–30 employees
Location
Россия
Representative
ruvds