Оператор ++ (int x) каждый раз создает новый экземпляр? - PullRequest
3 голосов
/ 22 августа 2010

Согласно MSDN, System.Int32 является неизменным, и его члены всегда возвращают новые экземпляры. Некоторый общий код, такой как цикл for, требует операции ++ довольно часто. Всегда ли приращение создает новые экземпляры и отбрасывает старые? Насколько я вижу, такой подход сильно повлияет на производительность. И мне интересно, как Microsoft это реализует.

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

Спасибо.

Ответы [ 3 ]

3 голосов
/ 22 августа 2010

Да и нет.

Ответ - да в том смысле, что это:

i++;

эквивалентно этому:

i = i + 1;

, что было бы эквивалентно этому (если бы System.Int32 имел конструктор с этой подписью):

i = new int(i + 1);

НО ...

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

Пространство для типа значения выделяется один раз в стеке. Когда вы пишете i = i + 1, это просто записывает новое значение в то же место в памяти. Это не новое выделение в куче.

На самом деле это деталь реализации; но это не меняет того факта, что ответ на то, что, на мой взгляд, вы действительно спрашиваете: «Требуется ли для записи i++ выделение некоторой новой памяти где-нибудь? - ответ на , что вопрос - нет.

Итак, проясним несколько моментов:

Всегда ли приращение создает новые экземпляры и отбрасывает старые?

Нет - это демонстрирует неправильное понимание того, как работают типы значений. Имеет смысл только сказать, что увеличение значения «отбрасывает старое», если типы значений размещаются в некотором пространстве, отличном от локального стека. Это правда, что старое значение перезаписано , но вряд ли вы найдете это удивительным.

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

Если в документации сказано, что все элементы Int32 являются поточно-ориентированными, это означает, что это относится к текущему значению. Фактически, любой неизменяемый тип будет поточно-ориентированным, потому что, если он не может быть изменен, он не может быть поврежден.

Вы должны понимать, что i++ - это не просто вызов метода для некоторого значения i; это присвоение из i новому значению. Эта операция - присвоение i новому увеличенному значению - не поточно-безопасна в том смысле, что два потока могут одновременно выполнять этот код одновременно, и вы можете получить новое значение i это только на 1 больше, чем предыдущее значение. Вот для чего Interlocked.Increment. Но документация MSDN не обманывает вас; внутреннее состояние i не может быть скомпрометировано многопоточным доступом.

1 голос
/ 22 августа 2010

System.Int32 не является ссылочным типом. Экземпляры не создаются путем распределения памяти так, как это делают классы.

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

Оператор ++ возвращает новое целое число таким образом, что семантически эквивалентно созданию нового экземпляра, но фактически не выделяет память для каких-либо экземпляров объекта.

0 голосов
/ 22 августа 2010

Без приращения (++) не является потокобезопасным.Документация MSDN правильная, но запутанная.Вы должны сосредоточиться на второй части.

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

что x+1 является потокобезопасным, поскольку само по себе не изменяет x (думайте об этом как о создании временного значения).Но присвоение x+1 x не является *. 1013 *

Документация также технически правильна, поскольку ++ не является членом System.Int32, это компилятор C #, который переводит x++до x = x + 1.

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