Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.67/6: Рейтинг темы: голосов - 6, средняя оценка - 4.67
2 / 2 / 2
Регистрация: 24.10.2013
Сообщений: 13

Новый экземпляр String?

10.01.2014, 22:55. Показов 1356. Ответов 17
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
C#
1
2
3
4
5
6
7
string str = "A";
///
 
for(;;;)
{
     Console.Write(str+"B");
}
Прошу прощения, если вопрос смешной: в приведённом примере каждый раз создаётся новая строка?
А то совсем запутался.
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
10.01.2014, 22:55
Ответы с готовыми решениями:

Ссылка на строку не ссылается на экземпляр String
Пытаюсь отослать массив клиенту, но после клиент зависает, так как на сервере вылетает ошибка. Не могу найти решение этой ситуации,...

Массив String - Ссылка на объект не указывает на экземпляр объекта
Доброго дня. Собственно, код функции поиска группы в домене по названию: // Описываем функцию проверки существования группы ...

Стоит ли создавать новый экземпляр класса для каждого запроса к бд?
Добрый день. Я новичок. Делую телеграмм бота, с обращением к базе данных из множества разных таблиц MySQL,С#. Вопрос:Читал, что каждый...

17
 Аватар для ViterAlex
8951 / 4863 / 1886
Регистрация: 11.02.2013
Сообщений: 10,246
10.01.2014, 23:16
да, каждый раз новая строка. А как иначе?
1
2 / 2 / 2
Регистрация: 24.10.2013
Сообщений: 13
11.01.2014, 00:10  [ТС]
Цитата Сообщение от ViterAlex Посмотреть сообщение
да, каждый раз новая строка. А как иначе?
Да просто голова не думает.

Допустим есть класс Person:

C#
1
2
3
4
5
6
7
8
class Person
    {
        string name;        
        /// 
        /// Всё остальное
        /// 
        public string Name { get { return name; } }
    }
Ну и есть
C#
1
2
3
4
5
6
7
8
9
static class Какой_НибудьКласс
    {
        static List<Person> people;
 
        ////// Всякое разное
 
        public static List<Person> People { get { return people; } }
 
    }
Причём всё это в другой сборке.

А я располагаю какой-нибудь функцией рисующей интерфейс, которая каждый кадр выводит мне список людей:

C#
1
2
3
4
5
6
7
8
9
10
11
12
//////
 
private void OnDraw()
        {
            Display("Люди:");
 
            foreach(Person p in Какой_НибудьКласс.People)
            {
                Display("Дядя-" + p.Name);
            }
 
        }
Нужно перед именем например вставить "Дядя-"(т.е. константная строка), как быть?
0
176 / 144 / 70
Регистрация: 01.05.2012
Сообщений: 414
11.01.2014, 00:24
Так а в чем проблема? Будет перед именем "Дядя-")
1
 Аватар для ViterAlex
8951 / 4863 / 1886
Регистрация: 11.02.2013
Сообщений: 10,246
11.01.2014, 00:24
Ну и выводи, как написал. Тебя смущает, что каждый раз новая строка создаётся?
Разве что я бы написал так:
C#
1
p.Name.Insert(0, "Дядя-");
1
2 / 2 / 2
Регистрация: 24.10.2013
Сообщений: 13
11.01.2014, 00:58  [ТС]
Цитата Сообщение от ViterAlex Посмотреть сообщение
Ну и выводи, как написал. Тебя смущает, что каждый раз новая строка создаётся?
Разве что я бы написал так:
C#
1
p.Name.Insert(0, "Дядя-");
Да, просто когда это делается по 60 раз в секунду для обширного списка, начинает смущать.
Хорошо, спасибо за ответы)

Добавлено чуть позже
....

Наверное проще создать какой-нибудь Dictionary<Person, string> myDictionary, и при инициализации в строку забить собственное представление имени:

C#
1
2
3
4
foreach(Person p in Какой_НибудьКласс.People)
            {
                myDictionary.Add(p, "Дядя-"+p.Name);
            }
и в
C#
1
2
3
4
5
6
7
8
9
10
private void OnDraw()
        {
            Display("Люди:");
 
            foreach(Person p in Какой_НибудьКласс.People)
            {
                Display(myDictionary[p]);
            }
 
        }
0
Master of Orion
Эксперт .NET
 Аватар для Psilon
6102 / 4958 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
11.01.2014, 01:48
ViterAlex, смысл инсерта? Просто ради инсерта? И да, в примере
C#
1
2
3
4
for(;;;)
{
     Console.Write(str+"B");
}
почти на 100% уверен, что будет создана одна строка AB.

А вот в
C#
1
2
3
4
foreach(Person p in Какой_НибудьКласс.People)
            {
                myDictionary.Add(p, "Дядя-"+p.Name);
            }
будет создано N строк.

Ничего страшного в этой записи нет, все корректно.

Добавлено через 1 минуту
см. интернирование:
http://habrahabr.ru/post/165597/
1
 Аватар для ViterAlex
8951 / 4863 / 1886
Регистрация: 11.02.2013
Сообщений: 10,246
11.01.2014, 07:48
Цитата Сообщение от Psilon Посмотреть сообщение
ViterAlex, смысл инсерта? Просто ради инсерта?
Нет, ради быстроты. Insert работает быстрее, чем соединение строк плюсом
0
 Аватар для akafeanor
60 / 59 / 15
Регистрация: 04.05.2010
Сообщений: 161
11.01.2014, 08:00
используй stringbuilder
0
Master of Orion
Эксперт .NET
 Аватар для Psilon
6102 / 4958 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
11.01.2014, 08:07
Цитата Сообщение от ViterAlex Посмотреть сообщение
Нет, ради быстроты. Insert работает быстрее, чем соединение строк плюсом
Да ну?

http://ideone.com/Bqm7tk

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
using System;
using System.Diagnostics;
using System.Linq;
using System.Runtime.CompilerServices;
 
namespace ConsoleApplication85
{
    class Program
    {
        static void Main()
        {
            int n = 100000;
            var results1 = new long[10];
            var results2 = new long[10];
            for (int i = 0; i < results1.Length; i++)
            {
                results1[i] = Test(0, n, Concat);
                results2[i] = Test(n, n, Insert);
            }
            Console.WriteLine("Concat = {0}{2}Insert = {1}", results1.Average(), results2.Average(), Environment.NewLine);
            Console.ReadKey();
        }
 
        private static long Test(int start, int n, Func<string,string,string> func)
        {
            var sw = Stopwatch.StartNew();
            var strings = new string[n];
            for (int i = 0, j = start; i < strings.Length; i++, j++)
            {
                strings[i] = func(j.ToString(), j.ToString());
            }
            sw.Stop();
            GC.Collect();
            GC.WaitForPendingFinalizers();
            GC.Collect();
            return sw.ElapsedMilliseconds;
        }
 
        [MethodImpl(MethodImplOptions.NoInlining)]
        private static string Concat(string a, string b)
        {
            return a + b;
        }
 
        [MethodImpl(MethodImplOptions.NoInlining)]
        private static string Insert(string a, string b)
        {
            return b.Insert(0, a);
        }
    }
}
2
 Аватар для ViterAlex
8951 / 4863 / 1886
Регистрация: 11.02.2013
Сообщений: 10,246
11.01.2014, 12:09
Я именно так и проверял. Только не считал среднее значение и выводил значение в тиках. И у меня получается, что Insert быстрее:

Code
1
2
3
В тиках:
Concat = 139687,2
Insert = 132887,6
Code
1
2
3
В миллисекундах:
Concat = 57,9
Insert = 56,2
А в тиках-то гора-а-аздо быстрее
Спасибо за хороший код
0
18 / 18 / 6
Регистрация: 10.01.2014
Сообщений: 45
11.01.2014, 13:34
Можно же разбирать IL код .Смотреть какие инструкции выполняются.
C#
1
2
3
4
5
6
7
8
 static void Main(string[] args)
        {
            string str = "A";
 
            string s1 = str + "B";
            
            string s2 = str.Insert(0, "B");         
        }
string s1 = str + "B";
C#
1
2
 IL_000d:  call       string [mscorlib]System.String::Concat(string,
                                                              string)
System.String::Concat метод статический . Для вызова используется инструкция call
Нет экземпляра, а значит нет проверки на null.


string s2 = str.Insert(0, "B");
C#
1
2
IL_001a:  callvirt   instance string [mscorlib]System.String::Insert(int32,
                                                                       string)
System.String::Insert - экземплярный метод. JIТ-компилятор
сначала сгенерирует код для проверки переменной str на null.
Из-за этого инструкция call выполняется быстрее чем инструкция callvirt.

рихтер clr via c# читаю
0
1195 / 588 / 88
Регистрация: 20.09.2012
Сообщений: 1,881
11.01.2014, 14:11
TeachMeC, это рассуждения ну о чем. Ни надо никуда смотреть, достаточно просто подумать.
"A".Insert(0, "B") и "A" + "B" выполняют совершенно одно и тоже, а именно - резервируют память под новую строку и копируют в нее содержимое старых. Т.о. это эквивалентные операции и они отрабатываю за практические одинаковое время (флуктуация в несколько процентов можно не рассматривать). Из-за кучи мелочей в реализации, под Mono (aka ideone) чуть работает быстрее "+", а под виндой чуть быстрее работает Insert.
Но "A" + "B" очевидно более читаемый вариант и смысла в использовании .Insert(0, нет под любой платформой.
А сравнивать это
Цитата Сообщение от TeachMeC Посмотреть сообщение
Из-за этого инструкция call выполняется быстрее чем инструкция callvirt.
, это вообще последнее чем нужно заниматься в жизни, если только не пытаться написать на С# real-time системы, но там стринги обычно клеют не так.
1
18 / 18 / 6
Регистрация: 10.01.2014
Сообщений: 45
11.01.2014, 14:18
Цитата Сообщение от pycture Посмотреть сообщение
это вообще последнее чем нужно заниматься в жизни,
Возможно вы правы. Просто мне это интересно .
Цитата Сообщение от pycture Посмотреть сообщение
Ни надо никуда смотреть, достаточно просто подумать.
Хотя такая фраза настораживает.
0
Master of Orion
Эксперт .NET
 Аватар для Psilon
6102 / 4958 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
11.01.2014, 15:11
ViterAlex, ну я запускал на разных компьютерах - и везде + чуть быстрее. Про удобочитаемость хотел сказать, но потом передумал, а потом и за меня все сказали.

Добавлено через 4 минуты
Напоминает мне, как я когда начинал программировать в паскале, экономил на памяти: объявлял переменную типа byte, а не int, рассуждая как: зачем мне тратить 3 лишних байта, я то точно знаю, что цикл маленький!.. А вот про то, что все равно выравнивается по 4 байта, неявное преобразование в int каждый раз и еще всякое интересное только замедляет и ухудшает код - и все же. Алсо, никогда не стоит писать a >>= 1 вместо a /= 2, или y = a&1 вместо y = a%2 и пр. Компилятор не дурак и сам умеет заменять деление сдвигами. Причем помню он даже уможение на 40 расписал как
x = a >> 6
y = a >> 3
res = x + y
0
1195 / 588 / 88
Регистрация: 20.09.2012
Сообщений: 1,881
11.01.2014, 15:30
Цитата Сообщение от TeachMeC Посмотреть сообщение
System.String::Concat метод статический . Для вызова используется инструкция call
Нет экземпляра, а значит нет проверки на null.
Вдогонку, для размышлений кусок из System.String
Кликните здесь для просмотра всего текста
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public static string Concat(string str0, string str1)
{
    if (string.IsNullOrEmpty(str0))
    {
        if (string.IsNullOrEmpty(str1))
        {
            return string.Empty;
        }
        return str1;
    }
    else
    {
        if (string.IsNullOrEmpty(str1))
        {
            return str0;
        }
        int length = str0.Length;
        string text = string.FastAllocateString(length + str1.Length);
        string.FillStringChecked(text, 0, str0);
        string.FillStringChecked(text, length, str1);
        return text;
    }
}
0
11.01.2014, 15:50

Не по теме:

Ну и что ?Значит все таки надо смотреть . Или нет?

Цитата Сообщение от pycture Посмотреть сообщение
Ни надо никуда смотреть, достаточно просто подумать.
Цитата Сообщение от pycture Посмотреть сообщение
Вдогонку, для размышлений кусок из System.String
pycture, спорить не собирался. Уверен вы кода нагенерировали побольше моего.
Ну и с шарпом я вообще не знаком. Так сказать, только прикоснулся к прекрасному.:)

0
11.01.2014, 16:35

Не по теме:

Цитата Сообщение от TeachMeC Посмотреть сообщение
Значит все таки надо смотреть . Или нет?
Для простых случаев, такие как этот, нужно думать. Для сложных, когда совсем невмоготу, можно и посмотреть, но это бывает крайне редко. Код я показал просто для наглядности (чтоб не обсуждать, что там в Рихтере написано), что проверки на null есть, и делать выводы основываясь только на сигнатурах методов занятие преждевременное.

1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
11.01.2014, 16:35
Помогаю со студенческими работами здесь

Что быстрее - после отработки кода, запускать новый экземпляр класса в новый поток или использовать рекурсию?
Собственно интересует такой вопрос, имеется класс реализующий интерфейс Runnable(нечто вроде ИИ), который запускается в отдельном потоке,...

Программа игнорирует новый экземпляр
Добрый день. В файловом сервере игнорируется новый экземпляр &quot;new HttpConnect(ss.accept())&quot;. Как решить проблему? Заранее благодарю. ...

Не создаётся новый экземпляр формы
Не создаётся новый экземпляр формы. ' *** Кнопка. Перечень открытых форм Private Sub btn_lst_OpenForm_Click() Call...

Неясная ошибка: Новый экземпляр проигнорирован
Только начинаю учить язык по 4-му изданию Философии Java, но примеры там не всегда корректны. Вот 5я глава, 1й пример. Я его уже...

Добавить новый экземпляр структуры в список
например есть струткура typedef { int id; char* text; } myStruc; теперь мне надо сделать её списком List


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

Или воспользуйтесь поиском по форуму:
18
Ответ Создать тему
Новые блоги и статьи
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
Управление камерой с помощью скрипта OrbitControls.js на Three.js: Вращение, зум и панорамирование
8Observer8 05.03.2026
Содержание блога Финальная демка в браузере работает на Desktop и мобильных браузерах. Итоговый код: orbit-controls-threejs-js. zip. Сканируйте QR-код на мобильном. Вращайте камеру одним пальцем,. . .
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip На первой гифке отладочные линии отключены, а на второй включены:. . .
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip Сканируйте QR-код на мобильном и вы увидите, что появится джойстик для управления главным героем. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru