Как зайти в Даркнет?!
25th January, 01:11
6
0
Как в tkinter из поля ввода Entry получить значение в одну переменную и обновить строку кнопкой, затем получить ещё одно введённое значение и затем сложить их. Ниже пример кода
21st July, 19:00
895
0
Программа, которая создает фейковые сервера в поиске игровых серверов CS 1.6 Steam
21st March, 17:43
948
0
Очень долго работает Update запрос Oracle
27th January, 09:58
914
0
не могу запустить сервер на tomcat HTTP Status 404 – Not Found
21st January, 18:02
905
0
Где можно найти фрилансера для выполнения поступающих задач, на постоянной основе?
2nd December, 09:48
938
0
Разработка мобильной кроссплатформенной военной игры
16th July, 17:57
1724
0
период по дням
25th October, 10:44
3955
0
Пишу скрипты для BAS только на запросах
16th September, 02:42
3720
0
Некорректный скрипт для закрытия блока
14th April, 18:33
4613
0
прокидывать exception в блоках try-catch JAVA
11th March, 21:11
4381
0
Помогите пожалуйста решить задачи
24th November, 23:53
6086
0
Не понимаю почему не открывается детальное описание продукта
11th November, 11:51
4351
0
Нужно решить задачу по программированию на массивы
27th October, 18:01
4396
0
Метода Крамера С++
23rd October, 11:55
4309
0
помогите решить задачу на C++
22nd October, 17:31
4002
0
Помогите решить задачу на python с codeforces
22nd October, 11:11
4492
0
Python с нуля: полное руководство для начинающих
18th June, 13:58
2599
0
Самый эффективный способ объединения строк?
Каков наиболее эффективный способ объединения строк?
У Рико Мариани, гуру перформанса № 33, была статья на эту тему. Это не так просто, как можно было бы предположить. Основной совет заключается в следующем:
Если ваш шаблон выглядит так:
x = f1(...) + f2(...) + f3(...) + f4(...)это один конкат, и это Зиппи, StringBuilder, вероятно, не поможет.
Если ваш шаблон выглядит так:
if (...) x += f1(...)
if (...) x += f2(...)
if (...) x += f3(...)
if (...) x += f4(...)тогда вы, вероятно, хотите StringBuilder.
Еще одна статья в поддержку этого утверждения исходит от Эрика Липперта, где он подробно описывает оптимизацию, выполненную на одной линии + конкатенаций.
Метод StringBuilder.Append() намного лучше, чем использование оператора+. Но я обнаружил, что при выполнении 1000 конкатенаций или меньше String.Join() еще более эффективен, чем StringBuilder .
StringBuilder sb = new StringBuilder();
sb.Append(someString);
Единственная проблема с String.Join заключается в том, что вам нужно объединить строки с общим разделителем. (Edit:) как было указано @ryanversaw, вы можете сделать разделитель string.Empty.
string key = String.Join("_", new String[]
{ "Customers_Contacts", customerID, database, SessionID });
Существует 6 типов конкатенаций строк:
- Используя символ плюса (
+). - Используя
string.Concat(). - Используя
string.Join(). - Используя
string.Format(). - Используя
string.Append(). - Используя
StringBuilder.
В эксперименте было доказано, что string.Concat() -это лучший способ приблизиться, если слов меньше 1000 (приблизительно), а если слов больше 1000, то следует использовать StringBuilder .
Для получения дополнительной информации посетите этот сайт .
string.Join() против string.Concat()
Метод string.Concat здесь эквивалентен вызову метода string.Join с пустым разделителем. Добавление пустой строки происходит быстро, но не делать этого еще быстрее, так что метод string.Concat будет здесь лучше.
От Chinh Do-StringBuilder не всегда быстрее :
эмпирическое правило
При объединении трех или менее динамических строковых значений используйте традиционную конкатенацию строк.
При объединении более трех динамических строковых значений используйте StringBuilder.
При построении большой строки из нескольких строковых литералов используйте либо литерал @ string, либо оператор inline+.
В большинстве случаев StringBuilder-это ваш лучший выбор, но есть случаи, как показано в этом посте, что вы должны, по крайней мере, думать о каждой ситуации.
Если вы работаете в цикле, то StringBuilder-это, вероятно, правильный путь; это экономит вам время на регулярное создание новых строк. Однако в коде, который будет выполняться только один раз, String.Concat, вероятно, подойдет.
Однако Рико Мариани (.NET оптимизация гуру) составил тест , в котором он заявил в конце, что в большинстве случаев он рекомендует String.Format.
Вот самый быстрый метод, который я разработал за десять лет для своего масштабного приложения NLP. У меня есть варианты для IEnumerable<T> и других типов входных данных , с разделителями разных типов ( Char, String) и без них, но здесь я показываю простой случай объединения всех строк в массиве в одну строку без разделителя. Последняя версия здесь разработана и протестирована на C# 7 и .NET 4.7 .
Существует два ключа к повышению производительности; первый-это предварительное вычисление точного общего требуемого размера. Этот шаг является тривиальным, когда входным сигналом является массив, как показано здесь. Для обработки IEnumerable<T> вместо этого стоит сначала собрать строки во временный массив для вычисления этого итога (массив необходим, чтобы избежать вызова ToString() более одного раза на элемент, поскольку технически, учитывая возможность побочных эффектов, это может изменить ожидаемую семантику операции 'string join').
Далее, учитывая общий размер распределения конечной строки, наибольшая производительность boost достигается при построении результирующей строки на месте . Для этого требуется (возможно, спорный) метод временного приостановления неизменности нового String , который изначально выделяется полным нулями. Однако любые подобные споры остаются в стороне...
..
обратите внимание, что это единственное решение массовой конкатенации на этой странице, которое полностью исключает дополнительный раунд выделения и копирования конструктором
String.
Полный код:
/// <summary>
/// Concatenate the strings in 'rg', none of which may be null, into a single String.
/// </summary>
public static unsafe String StringJoin(this String[] rg)
{
int i;
if (rg == null || (i = rg.Length) == 0)
return String.Empty;
if (i == 1)
return rg[0];
String s, t;
int cch = 0;
do
cch += rg[--i].Length;
while (i > 0);
if (cch == 0)
return String.Empty;
i = rg.Length;
fixed (Char* _p = (s = new String(default(Char), cch)))
{
Char* pDst = _p + cch;
do
if ((t = rg[--i]).Length > 0)
fixed (Char* pSrc = t)
memcpy(pDst -= t.Length, pSrc, (UIntPtr)(t.Length << 1));
while (pDst > _p);
}
return s;
}
[DllImport("MSVCR120_CLR0400", CallingConvention = CallingConvention.Cdecl)]
static extern unsafe void* memcpy(void* dest, void* src, UIntPtr cb);
Я должен отметить, что этот код имеет небольшое изменение от того, что я использую сам. В оригинале я вызываю инструкцию cpblk IL из C# , чтобы сделать фактическое копирование. Для простоты и переносимости кода здесь Я заменил его на P/Invoke memcpy , как вы можете видеть. Для более высокой производительности на x64 (но, возможно, не x86) вы можете использовать метод cpblk вместо этого.
Из этой статьи MSDN :
Есть некоторые накладные расходы, связанные с создание объекта StringBuilder, оба во времени и памяти. На машине с быстрая память, a StringBuilder становится стоит, если вы делаете около пяти оперативный. В качестве эмпирического правила, я скажем, 10 или более строковых операций является ли оправдание накладных расходов на любая машина, даже более медленная.
Поэтому, если Вы доверяете MSDN, идите с StringBuilder, если вам нужно сделать более 10 операций со строками / конкатенаций - в противном случае простая строка конкат с ' + ' подойдет.
Добавляя к другим ответам, пожалуйста, имейте в виду, что StringBuilder можно указать начальный объем памяти для выделения .
Параметр capacity определяет максимальное количество символов, которые могут храниться в памяти, выделенной текущим экземпляром. Его значение присваивается свойству Capacity . Если количество символов, хранящихся в текущем экземпляре, превышает это значение емкости , объект StringBuilder выделяет дополнительную память для их хранения.
Если емкость равна нулю, используется емкость по умолчанию для конкретной реализации.
Многократное добавление к StringBuilder, которое не было предварительно выделено, может привести к большому количеству ненужных выделений, как и многократное объединение обычных строк.
Если вы знаете, какой длины будет конечная строка, можете тривиально вычислить ее или сделать обоснованное предположение об общем случае (выделение слишком большого количества не обязательно плохо), вы должны предоставить эту информацию конструктору или свойству Capacity . Особенно при выполнении тестов производительности для сравнения StringBuilder с другими методами, такими как String.Concat, которые делают то же самое внутренне. Любой тест, который вы видите в интернете, который не включает в свои сравнения предварительное выделение StringBuilder, является неправильным.
Если вы не можете сделать никаких предположений о размере, вы, вероятно, пишете служебную функцию, которая должна иметь свой собственный необязательный аргумент для управления предварительным распределением.
Также важно отметить, что при объединении строковых литералов следует использовать оператор + .
При объединении строковых литералов или строковых констант с помощью оператора + компилятор создает одну строку. Конкатенация во время выполнения не происходит.
Как объединить несколько строк (C# руководство по программированию)
Наиболее эффективным является использование StringBuilder, вот так:
StringBuilder sb = new StringBuilder();
sb.Append("string1");
sb.Append("string2");
...etc...
String strResult = sb.ToString();
@jonezy: String.Concat прекрасно, если у вас есть пара небольших вещей. Но если вы объединяете мегабайты данных, ваша программа, скорее всего, будет работать.
Попробуйте эти 2 части кода, и вы найдете решение.
static void Main(string[] args)
{
StringBuilder s = new StringBuilder();
for (int i = 0; i < 10000000; i++)
{
s.Append( i.ToString());
}
Console.Write("End");
Console.Read();
}
Против
static void Main(string[] args)
{
string s = "";
for (int i = 0; i < 10000000; i++)
{
s += i.ToString();
}
Console.Write("End");
Console.Read();
}
Вы обнаружите, что 1-й код закончится очень быстро, и память будет в хорошем количестве.
Второй код, возможно, память будет в порядке, но это займет больше времени... гораздо дольше. Поэтому, если у вас есть приложение для большого количества пользователей, и вам нужна скорость, используйте 1-й. если у вас есть приложение для краткосрочного использования одного пользовательского приложения, возможно, вы можете использовать оба или 2-й будет более "natural" для разработчиков.
Овации.
Это действительно зависит от вашего шаблона использования. Подробный бенчмарк между string.Join, string, Concat и string.Format можно найти здесь: String.Format не подходит для интенсивного ведения журнала
(На самом деле это тот же самый ответ, который я дал на этот вопрос)
System.String является неизменным. Когда мы изменяем значение строковой переменной, то новая память выделяется на новое значение и предыдущее выделение памяти освобождается. System.StringBuilder был разработан, чтобы иметь понятие изменяемой строки, где различные операции могут быть выполнены без выделения отдельного места памяти для измененной строки.
Для всего лишь двух строк вы определенно не хотите использовать StringBuilder. Существует некоторый порог, выше которого накладные расходы StringBuilder меньше, чем накладные расходы на выделение нескольких строк.
Итак, для более чем 30 строк используйте код DannySmurf . В противном случае просто используйте оператор+.
Все будет зависеть от кода. StringBuilder в целом более эффективен, но если вы объединяете только несколько строк и делаете все это в одной строке, оптимизация кода, скорее всего, позаботится об этом за вас. Важно также подумать о том, как выглядит код: для больших наборов StringBuilder облегчит чтение, для маленьких StringBuilder просто добавит ненужный беспорядок.