Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.98/43: Рейтинг темы: голосов - 43, средняя оценка - 4.98
 Аватар для belalugoci
475 / 294 / 29
Регистрация: 01.06.2018
Сообщений: 3,676

Ботлнек String/StringBuilder

22.11.2020, 08:42. Показов 11558. Ответов 220
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
обсуждение, начавшееся в другой теме переношу сюда. Самой тяжёлой является операция:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
string source = File.ReadAllText(@"d:\work\words\source.txt", Encoding.GetEncoding(1251));
var sb_source = new StringBuilder(source, Source.Length);
Dictionary<string, int> F = new Dictionary<string, int>();
// ---
// тут вставляем код заполнения F, у меня получается около 70000 пар
// заполнение происходит очень быстро
// ---
foreach (var elem in F)
{
    // а вот тут был string и работало это, как мы все понимаем 200 лет
    // теперь тут StringBuilder, работает быстрее, но не слишком
    // можно сделать Parallels.ForEach, для моего i5 ускорится в ~4 раза
    sb_source = sb_source.Replace(elem.Key, "\0\0\0");
};
Нолики "\0" - это классификатор отсутствия информации, то есть после нескольких итераций на выходе будет файл полностью забитый нулями. Это один из показателей верности работы алгоритма.
Получается для файла в 4 мб (гигабайты я пока использовать не стал) это 4*70000=280000 Мбайт чтения и поменьше записи в памяти. Возможно стоит перевести на массив byte[] или ulong[] и делать замену вручную.

Добавлено через 10 минут
Цитата Сообщение от belalugoci Посмотреть сообщение
можно сделать Parallels.ForEach, для моего i5 ускорится в ~4 раза
StringBuilder также не является потокобезопасным, поэтому его работа с параллельными потоками недопустима.
Видимо нельзя
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
22.11.2020, 08:42
Ответы с готовыми решениями:

List<string, string, string> есть ли в C# что-то подобное?
Мне надо добавить в List не только имя файла, но и некоторые строки из этого файла. Т.е. например, у меня есть в определенном директории...

StringBuilder и регулярки
Подскажите, можно ли на StringBuilder использовать RegEx.Replace? Если да, то как?

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

220
 Аватар для belalugoci
475 / 294 / 29
Регистрация: 01.06.2018
Сообщений: 3,676
23.11.2020, 19:04  [ТС]
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Я не совсем понимаю, что делает ваш код.
это 1/8 от сбора ключей, сейчас у меня всё что происходит не соответствует реальной потребности, то есть результат переизбыточен по ключам и я пока не могу придумать как их отфильтровать. проблема в том, что они пересекаются, то есть например для строки:
1234567890
в словарь попадает
123
234
345
456
567
678
789
890

при этом в реальности должны были попасть
123
567

например.
К несчастью для меня, я не могу озвучить критерии отбора ключей. Поэтому это одиночное плавание, а зная мои способности оно будет дооооолгим. Но вы и так помогли очень много.

Цитата Сообщение от Элд Хасп Посмотреть сообщение
Если правильно понял, то что-то подобное:
Код мне непонятен.
0
Just Do It!
 Аватар для XLAT
4220 / 2684 / 656
Регистрация: 23.09.2014
Сообщений: 9,240
Записей в блоге: 3
23.11.2020, 19:04
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Я не совсем понимаю, что делает ваш код.
как такого там и кода то нет,
просто намёк на сам принцип,

был бы код оформлен как тест, то я бы поучаствовал в вашем соревновании, может быть
а так лень с нуля всё дописывать
0
 Аватар для belalugoci
475 / 294 / 29
Регистрация: 01.06.2018
Сообщений: 3,676
23.11.2020, 19:05  [ТС]
Цитата Сообщение от XLAT Посмотреть сообщение
ну это просто вариант
ну что вы, мой уровень - это Бейсик и Hello World.
0
Just Do It!
 Аватар для XLAT
4220 / 2684 / 656
Регистрация: 23.09.2014
Сообщений: 9,240
Записей в блоге: 3
23.11.2020, 19:20
Цитата Сообщение от belalugoci Посмотреть сообщение
мой уровень
ну, нет.

если вам надо, чтобы ваш код работал быстро, то вы уже как Полухин с яндекса,
который минимум уже 3 года как, пишет каждый раз новый логер для яндекс-такси,
который вроде всё быстрее и быстрее предыдущего:
Кликните здесь для просмотра всего текста
Цитата Сообщение от XLAT
...
На счёт Полухина:
сдаётся мне что он уже лет 5 переписывает логер с жабы на кресты.
на эту тему я видел у него ролик уже много лет назад, а этот ролик походу свежий.
https://www.cyberforum.ru/blog... g6736.html


0
23.11.2020, 19:25  [ТС]

Не по теме:

Цитата Сообщение от XLAT Посмотреть сообщение
ну, нет.
выше головы не прыгнешь, я на программировании поставил крест 20 лет назад, нет способностей. только в интернете обещают за 20 дней сделать человека программистом :D мне просто процесс доставляет удовольствие, но я часто прыгаю с темы на тему.

0
Just Do It!
 Аватар для XLAT
4220 / 2684 / 656
Регистрация: 23.09.2014
Сообщений: 9,240
Записей в блоге: 3
23.11.2020, 20:06
belalugoci,
имхо,
решение должно быть такое:
предположу, что ключи в дикшенери и в файле это числовые значения, хотя роли это особой не играет,
но просто для того чтобы представлять конкретную реализацию
1. сграбить файл в целочисленный массив Array.
2. ключи-числа также поместить в словарь(это нужно чтобы заюзать бинарный поиск)
3. брать число из Array и проверять его наличие в словаре.
4. если оно там, то присваивать нуль.
5. по окончании всей обработки можно вернуть Array в строку.

в чём изюминка? изюминка в быстром бинарном поиске!

в вашем примере из шапке бинарный поиск ВАЩЕ не задействован!
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,175
Записей в блоге: 2
23.11.2020, 20:09
Цитата Сообщение от belalugoci Посмотреть сообщение
Код мне непонятен.
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
    /// <summary>Классы для пары ключ-количество.
    /// Помогает избежать дубоипующих запросов по словарю.</summary>
    public class FreqPair
    {
        public ulong Key { get; }
        public int Count { get; set; }
 
        public FreqPair(ulong key) => Key = key;
 
        public FreqPair(ulong key, int count)
            : this(key)
            => Count = count;
    }
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
       /// <summary>Возвращает словарь ключей и их количство в тексте.</summary>
       /// <param name="fileName">Имя файла в байтовой кодировке. Например, ASCII текст. </param>
       /// <param name="keyLength">Длина ключа.</param>
       /// <returns>Все найденные ключи и их количество.</returns>
       
        public unsafe static IDictionary<ulong, FreqPair> GetFreqs(string fileName, int keyLength)
        {
            if (keyLength < 1 || keyLength > 8)
                throw new ArgumentOutOfRangeException(nameof(keyLength));
 
            // Чтение всего файла в байтовый массив.
            byte[] source = File.ReadAllBytes(fileName);
 
            // Словарь для ключей. Количество ключей накапливается в свойстве Count значения словаря.
            Dictionary<ulong, FreqPair> freqs = new Dictionary<ulong, FreqPair>();
 
            // Переменная для ключа. Объявляется в не цикла чтобы не генерировать мусор.
            ulong key = 0;
            // Байтовая ссылка на ключ. Позволяет обращаться по адрессу к отдельным баытам ключа.
            byte* keyBytes = (byte*)&key;
 
            // Формирование первого ключа
            // Состоит из первых keyLength байтов источника
            // Запись байт обратная.
            for (int i = 0; i < keyLength; i++)
            {
                *(keyBytes + keyLength - 1 - i) = source[i];
            }
            // Добавление первого ключа в словарь.
            freqs.Add(key, new FreqPair(key, 1));
 
            // Цикл по всем байтом, кроме первых keyLength уже записанных в словарь.
            for (int i = keyLength; i < source.Length; i++)
            {
                // Очищается старшый байт ключа.
                *(keyBytes + keyLength - 1) = 0;
                // Ключ смещается на один байт
                key <<= 8;
                // В младший байт ключа
                *keyBytes = source[i];
                // В результате получаем в key последовательно
                // всю нарезку массива source по keyLength байт
                
                // Ищем ключ в словаре
                // Если находим - увеличиваем количество.
                // Иначе добавляем новый ключ с количеством = 1.
                if (freqs.TryGetValue(key, out FreqPair pair))
                    pair.Count++;
                else
                    freqs.Add(key, new FreqPair(key, 1));
 
            }
 
            return freqs;
        }
Цитата Сообщение от belalugoci Посмотреть сообщение
в словарь попадает
Я так и релизовал.
Длина ключа от 1 до 8 передаётся в параметре метода.

Добавлено через 23 секунды
А вот что дальше с этими ключами надо делать?
1
Just Do It!
 Аватар для XLAT
4220 / 2684 / 656
Регистрация: 23.09.2014
Сообщений: 9,240
Записей в блоге: 3
23.11.2020, 20:32
Цитата Сообщение от Элд Хасп Посмотреть сообщение
А вот что дальше с этими ключами надо делать?
брать число из файла и проверять его на наличие в словаре,
если оно там, то вроде автор хочет обнулять.

словарь тут и не словарь - в крестах можно было бы использовать стл контейнер <set>,
смыл в том что оно внутрях отсортировано и можно быстро там искать.


Добавлено через 1 минуту
Итого:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
var list = new List<string>();
Dictionary<string, int> F = new Dictionary<string, int>();
// ---
// тут вставляем код заполнения F, у меня получается около 70000 пар
// заполнение происходит очень быстро
// ---
string res;
using (StreamReader sr = new StreamReader("text.txt", System.Text.Encoding.Default))
{
    string line = sr.ReadLine();
    if(F.ContainsKey(line)) line = "0";
    res += line;
}
буду ждать автора, шоп потестил
0
 Аватар для belalugoci
475 / 294 / 29
Регистрация: 01.06.2018
Сообщений: 3,676
23.11.2020, 20:37  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Я так и релизовал
+- понятно

Цитата Сообщение от Элд Хасп Посмотреть сообщение
А вот что дальше с этими ключами надо делать?
ох, а теперь мне нужно купить шапочку которая защитит мой мозг от взрыва и придумать решение как собрать уникальные ключи. Спасибо за варианты решений. В текущем варианте для 3 байт ключей весь мой код работает ровно 1 минуту для 850 Кб данных. У меня всё еще половина кода на String, но его я показывать не могу, попробую увиденные и показанные наработки применить.

Цитата Сообщение от XLAT Посмотреть сообщение
если оно там, то вроде автор хочет обнулять
обнуление не цель, а часть алгоритма формирования ключей, вроде мысли есть переделать на интервалы, но пока не знаю как реализовать, возможно List<> использовать для хранения интервалов и по определенному алгоритму эти интервалы убирать. По идее в итоге будет список интервалов, дающих в сумме один сплошной интервал соответствующий оригинальному файлу.
0
Just Do It!
 Аватар для XLAT
4220 / 2684 / 656
Регистрация: 23.09.2014
Сообщений: 9,240
Записей в блоге: 3
23.11.2020, 20:43
Цитата Сообщение от belalugoci Посмотреть сообщение
обнуление не цель
цель мне не известна,
я всего лишь показал вам эквивалент вашего кода из шапки, который по моей идее должен работать КРАТНО быстрее.

Добавлено через 2 минуты
я даже не знаю формат вашего файла, а это критично чтобы придумать, как поступить.
0
 Аватар для belalugoci
475 / 294 / 29
Регистрация: 01.06.2018
Сообщений: 3,676
23.11.2020, 20:51  [ТС]
Цитата Сообщение от XLAT Посмотреть сообщение
C#
1
2
3
4
5
6
7
string res;
using (StreamReader sr = new StreamReader("text.txt", System.Text.Encoding.Default))
{
    string line = sr.ReadLine();
    if(F.ContainsKey(line)) line = "0";
    res += line;
}
это что-то совсем не то, я правильно понимаю что line переменной длины?

у меня сейчас заполнение нулями делается так для 1 байта
C#
1
2
3
4
5
6
7
8
9
10
string source = File.ReadAllText(@"d:\work\words\a.txt", Encoding.GetEncoding(1251));
byte[] byte_source = System.Text.Encoding.GetEncoding(1251).GetBytes(source);
int i2 = 0;
while (i2 < len)
{
    byte[] codesym_byte = new byte[1] { byte_source[i2] };
    if (FreqOrdered1.ContainsKey(Encoding.GetEncoding(1251).GetString(codesym_byte)))
        byte_source[i2] = 0;
    i2++;
}
не обращаем внимания на первые две строки, я знаю что можно сразу читать в байт[].
как ни странно, но вариант с компаратором byte[] работает медленнее, хоть и не сильно, но на файле в 1гб это заметно.
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,175
Записей в блоге: 2
23.11.2020, 20:52
Цитата Сообщение от belalugoci Посмотреть сообщение
обнуление не цель...
Вот этот момент и не понятен.
Если просто заменять все найденные ключи нулями, то ни какой скользящей нарезки не будет.
Будет просто деления файла на куски заданного размера.
И каждый кусок и будет ключом.

То есть из 1234567890 при длине два мы получим про подряд все куски: 12, 34, 56, 78, 90.
0
 Аватар для belalugoci
475 / 294 / 29
Регистрация: 01.06.2018
Сообщений: 3,676
23.11.2020, 20:52  [ТС]
del
0
Эксперт .NET
6691 / 4102 / 1607
Регистрация: 09.05.2015
Сообщений: 9,576
23.11.2020, 20:53
Цитата Сообщение от belalugoci Посмотреть сообщение
как ни странно, но вариант с компаратором byte[] работает медленнее
Все 3 варианта компаратора проверили? Ну и плюс может там где-то в другом месте неоптимально кроме этого... Не должен вариант с ключем byte[] вместо string быть медленнее...
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,175
Записей в блоге: 2
23.11.2020, 20:55
Цитата Сообщение от belalugoci Посмотреть сообщение
у меня сейчас заполнение нулями делается так для 1 байта
Уберите двойную конвертацию файла.
Получайте сразу байтовый массив:
C#
1
byte[] byte_source = File.ReadAllBytes(@"d:\work\words\a.txt");
Добавлено через 1 минуту
Цитата Сообщение от belalugoci Посмотреть сообщение
Цитата Сообщение от XLAT Посмотреть сообщение
я даже не знаю формат вашего файла, а это критично чтобы придумать, как поступить.
тестовый файл
Текстовый ASCII.
То есть байтовый изначально.
0
 Аватар для belalugoci
475 / 294 / 29
Регистрация: 01.06.2018
Сообщений: 3,676
23.11.2020, 20:56  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
То есть из 1234567890 при длине два мы получим про подряд все куски: 12, 34, 56, 78, 90
12, 23, 34, 45, 56, 67, 78, 89, 90 - скорее так.

Цитата Сообщение от Элд Хасп Посмотреть сообщение
Если просто заменять все найденные ключи нулями, то ни какой скользящей нарезки не будет.
Будет просто деления файла на куски заданного размера.
И каждый кусок и будет ключом.
так-так, появились новые мысли у меня, главное не уснуть и не забыть.
со стороны так и есть.
0
 Аватар для belalugoci
475 / 294 / 29
Регистрация: 01.06.2018
Сообщений: 3,676
23.11.2020, 20:57  [ТС]
Цитата Сообщение от XLAT Посмотреть сообщение
я даже не знаю формат вашего файла
этим пользуюсь
Вложения
Тип файла: zip 20000 Leagues Under the Sea.zip (298.7 Кб, 6 просмотров)
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,175
Записей в блоге: 2
23.11.2020, 21:00
Цитата Сообщение от belalugoci Посмотреть сообщение
12, 23, 34, 45, 56, 67, 78, 89, 90 - скорее так.
Это мы получим такие ключи.
А в замене будут участвовать только указанные мною.
Я поэтому и не пойму, зачем считать ключи, которые не будут использоваться в замене?
0
 Аватар для belalugoci
475 / 294 / 29
Регистрация: 01.06.2018
Сообщений: 3,676
23.11.2020, 21:01  [ТС]
Цитата Сообщение от Someone007 Посмотреть сообщение
Все 3 варианта компаратора проверили?
нет, я думал они однаковые

Цитата Сообщение от Someone007 Посмотреть сообщение
Ну и плюс может там где-то в другом месте неоптимально кроме этого
завтра попробую все варианты и накидаю тестов

Цитата Сообщение от Элд Хасп Посмотреть сообщение
Уберите двойную конвертацию файла.
Получайте сразу байтовый массив
мне нужен текстовый вариант дальше по коду, там еще не переделано.
0
Just Do It!
 Аватар для XLAT
4220 / 2684 / 656
Регистрация: 23.09.2014
Сообщений: 9,240
Записей в блоге: 3
23.11.2020, 21:09
Цитата Сообщение от belalugoci Посмотреть сообщение
это что-то совсем не то,
ну вы верно поправили - я про while,
изначально он там и был но с копипастой я промахнулся...
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
23.11.2020, 21:09

Невозможно очистить StringBuilder после исключения OutOfMemoryException
Привет всем. Делаю небольшой текстовый редактор и натолкнулся на следующую проблему: при загрузке достаточно большого файла через...

StringBuilder: Строка не корректно создается, перемешиваются все поля
приложение клиент-сервер. клиент создает запрос на сервер, сервер с помощью StringBuilder из словаря формирует строку для передачи по...

В чем разница между StringWriter и StringBuilder и когда нужно использовать эти классы?
Подскажите, пожалуйста, в чем разница между StringWriter и StringBuilder и когда нужно использовать эти классы? То, что есть в этих...

Несколько вопросов по примеру из книги по C# про строки (string и String.Format)
Я нашел такой пример кода: private void butFormatStr_Click(object sender, EventArgs e { string AutoName; AutoName =...

Реализация интерфейса IEqualityComparer для HashSet<Dictionary<string, string>>
Код выдает &quot;2&quot;, что, логично, а хотелось бы, чтобы выдавал &quot;1&quot;, так как содержание словарей одинаковое. Подскажите, пожалуйста,...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
60
Ответ Создать тему
Новые блоги и статьи
Беседа с ИИ о программистах, недопускающих к созданию и правке кода генеративные ИИ и причины этого
zorxor 21.09.2026
Раньше я радовался или получал некоторые эмоции, пусть не большие, но всё же, от самого процесса написания кода, рекомпиляции и запуска, видя постепенное развитие программы и прочее. А теперь лень. . .
Мобильное приложение ColorStep
pavlinmavlin 17.09.2026
Реализовал приложение Красный, Зеленый, Синий в Unity3d + c#. Название изменил на ColorStep. Приложение прошло модерацию и теперь доступно для скачивания. Делал его сам, шаг за шагом — и вот,. . .
Запрет дублирования строк в табличной части
Maks 13.09.2026
Реализация из решения ниже выполнена на нетиповом справочнике "Нормы ТО" с табличной часть "Виды ТО", разработанного в КА2, со следующими реквизитами: - ВидТО (СправочникСсылка. ВидыТО); - ВидГСМ. . .
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр.
Jin X 06.09.2026
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр. Работая с форумом и нейросетями в браузере часто хочется что-то подкорректировать или добавить какого-то функционала. Ниже прикреплён. . .
Программа опроса у.з. расходомера SLS-720F
Argus19 02.09.2026
Программа опроса у. з. расходомера SLS-720F Программа опрашивает один раз в минуту три ультразвуковых расходомера SLS-720F через интерфейс RS-485 по протоколу Modbus RTU. Опрашиваются регистры. . .
Hyper-V: Компьютер должен поддерживать доверенный платформенный модуль 2.0.
Maks 31.08.2026
При установке Windows 11 на виртуальную машину Hyper-V 2-го поколения вылезла такая ошибка: Решение: в параметрах виртуальной машины, в разделе "Безопасность" (Security) активировать флаг. . .
Архитектура биовида Стива в Майнкрафте: Зачем бонобо кубический каннибализм
anaschu 30.08.2026
Кубический Вагинокапитализм в Minecraft: Математический инвариант ОДУ и рок Стивов-бонобо Главная задача разработанной «Модели Всего» — наглядно продемонстрировать наличие системной «судьбы». . .
Оттачиваю умение писать js программы.
russiannick 30.08.2026
Проектом выходного дня стало написание Книги шифров Виженера. Итогом стала версия 200, синий туман. Синий туман назван так, потому что замораживает текст под собой. Нажатие синих кнопок управляют. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru