Pull to refresh
-4
0
Александр Радченко @ARad

Разработчик

Send message

У вас нигде в статье не написано что НЕ надо писать реализации типа Jump вот в чем моё уточнение. Либо если вы такое написали, то очень незаметно или неявно.

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

@Zara6502мне кажется вы не правы, в том плане что как раз в вашей статье все внимание уделено узко специализированному алгоритму. А его даже не надо было делать. Нужно было просто убрать неоптимальные моменты метода Split и всё. И это просто сделать. Т.е. нужно было сделать быстрый алгоритм ленивого перечисления слов в строке и всё. Ленивое перечисление это ключевой момент, так так позволяет избавится от большого потребления памяти. Дальше можно легко выполнять любую необходимую обработку слов. Да он будет в 2-5 раз дольше работать для частного случая, но его можно будет легко менять под большинство требований.

Я не нашёл у `ReadOnlyMemory` метода SplitAny с одним параметром, похоже вы его сами написали?

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

Полностью поддерживаю автора, по концепции, не люблю я писать сложные алгоритмы которые тяжело поддерживать при изменении требований.
Лучше написать простую и достаточно эффективную реализацию, которая пусть даже в 5-10 раз медленнее, но которую легко менять под изменения.
Грубо говоря я бы сделал алгоритм который бы быстро и лениво возвращал следующее слово без учёта всяких других требований.
А вот вокруг него уже можно натянуть какие хочешь требования бизнеса. Да конкретно для поиска самого длинного слова он будет примерно в 3 раза медленнее, но если требования будут меняться, добавляться, его поддерживать буде раз в 100 быстрее. А это важнее...

Насчёт конкретной реализации я думаю что у автора не самая удачная. Можно лучше и проще.

Да обновил до версии UPD3, видать невнимательно скопировал.
Этот вариант не проходит тесты, к сожалению. Jump return 15 should 14

Он возращает что самое длинное слово имеет длину 15, по моим расчётам должна быть 14.

LongestWord = Regex.Split(Words, "[^a-zA-Z]+").Max(word => word.Length);

Я использую такую регулярку для проверки.

В главном цикле нет прыжков

for (int i = 0; i < len - maxlen; i++)

https://github.com/AlexRadch/dotNetMisc HabrMisc\LongestWordLength\LongestWordLength.sln

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

| TwoLoops      | 100000     | 3,674.812 μs | 71.7678 μs | 95.8080 μs | 3,645.900 μs |     736 B |
| TwoLoops1Jump | 100000     | 1,283.652 μs | 29.3687 μs | 83.3142 μs | 1,278.200 μs |     736 B |
| Jump          | 100000     | 3,133.623 μs | 48.3515 μs | 40.3757 μs | 3,129.000 μs |     736 B |
| JumpNew       | 100000     | 3,255.214 μs | 61.6167 μs | 54.6216 μs | 3,239.050 μs |     736 B |

Насчёт циклов вы не правы. Любой цикл компилируется в условные переходы. В дотНет достаточно неплохой компилятор циклов, хоть и не идеальный.

Вы нашли у себя неоптимальности в главном цикле? Там у вас шаг по одному символу, я поэтому дальше смотреть код не стал, там явно ошибка...

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

Небольшая оптимизация

    public static int TwoLoops1Jump(string str)
    {
        var maxLength = 0;

        for (int endIndex = 0, len = str.Length; endIndex < len; endIndex += maxLength + 1)
        {
            if (!char.IsAsciiLetter(str[endIndex]))
                continue;

            // Can IndexOf be faster here?
            var startIndex = endIndex - maxLength;
            for (var breakIndex = endIndex - 1; breakIndex > startIndex; breakIndex--)
            {
                if (!char.IsAsciiLetter(str[breakIndex]))
                {
                    endIndex = breakIndex;
                    goto Continue;
                }
            }
            if (!char.IsAsciiLetter(str[startIndex]))
                startIndex++;

            // Can IndexOf be faster here?
            while (++endIndex < len && char.IsAsciiLetter(str[endIndex])) ;

            maxLength = endIndex - startIndex;

        Continue:
            ;
        }

        return maxLength;
    }

    public static int FastTwoLoops(string str)
    {
        var maxLength = 0;

        for (int startIndex = 0, endIndex = 0; endIndex < str.Length;
            startIndex = ++endIndex, 
            endIndex += maxLength)
        {
            if (!char.IsAsciiLetter(str[endIndex]))
                continue;

            for (var breakIndex = endIndex - 1; breakIndex >= startIndex; breakIndex--)
            {
                if (!char.IsAsciiLetter(str[breakIndex]))
                {
                    endIndex = breakIndex;
                    goto Continue;
                }
            }

            while (++endIndex < str.Length && char.IsAsciiLetter(str[endIndex])) ;
            maxLength = endIndex - startIndex;

        Continue:
            ;
        }

        return maxLength;
    }

Мой вариант алгоритма с прыжками, у вас как то путано показалось написано...

Да в .Net 7 нет вариантов которые ускорят обычный алгоритм, согласен.

В .Net 8 возможно можно ускорить обычный алгоритм. Там уже работа со спанами, что достаточно неудобно и это может помешать производительности... В общем у меня тут тоже сомнения что могут...

Алгоритм с прыжками этими методами уже не ускорить к сожалению.

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

Если вы хотите быстрое решение, то всё таки в первую очередь надо знать и использовать стандартные методы. А именно использование IndexOf метода должно поднять производительность относительно поиска в циклах как у вас. Особенно если вы будете использовать .Net 8 варианты этого метода.

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

Мы сейчас придем к другой философской проблеме - существуют-ли в природе действительно случайные процессы?

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

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

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

УК это не ФС вообще.

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

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

То что природу нельзя познать на 100% процентов, это понятно всем учёным. Как отсюда следует что правы субъективисты непонятно. Да и в чем правы то? Я не понял...

Пока что понятно что всё можно описать математическими законами, но мы этого никогда не сможем сделать... Тут нет противоречия.

Алгоритмы могут включать случайности. Так пишут многие программы, особенно для игр. Да и современные нейросети особенно для рисования обязательно включают в себя случайности. Без этого они были бы скучными и не выдавали такого многообразия рисунков.

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

Information

Rating
5,245-th
Location
Паттая, Чон Бури, Таиланд
Date of birth
Registered
Activity

Specialization

Fullstack Developer, Application Developer
Senior
From 2,000 $
C#
.NET
Algorithms and data structures
Multiple thread
Code Optimization
System Programming
Applied math
Database
High-loaded systems
Designing application architecture