#c# #.net #memory #types
#c# #.net #память #типы
Вопрос:
Я тестирую матрицу, содержит ли она простое число в каждой строке.
MR означает, что он должен использовать алгоритм Миллера-Рабина. Если значение равно false, он просто пробует делители с точностью до sqrt (n). Значение Vansor равно true, если оно нашло простое число в каждой проверенной строке, значение vanoszlop равно true, если оно нашло простое число в фактически проверенной строке.
Мой вопрос: возможно ли сохранить память, не создавая значения int и BigInteger, только если TryParse имеет значение true? Я имею в виду что-то вроде
if (int.tryParse(akt, out new int szam))
Возможно ли что-то подобное? (и сколько памяти занимает BigInteger, когда он не подписан?)
akt = Console.ReadLine();
int szam; BigInteger szambig;
if (int.TryParse(akt, out szam))
{
if (MR) {
if (MilRab(szam))
{ vansor = true; vanoszlop = true; } }
else if (Prim(szam))
{ vansor = true; vanoszlop = true; }
}
else if (BigInteger.TryParse(akt, out szambig))
{
if (MR) {
if (MilRab(szam))
{ vansor = true; vanoszlop = true; } }
else if (Prim(szam))
{ vansor = true; vanoszlop = true; }
}
Комментарии:
1. Лучше спросите, было бы разумно. Ответ был бы отрицательным. Вы говорите о двух локальных переменных с очень небольшим объемом. Большая часть BigInt выделяется только тогда, когда она назначена.
2. Почему вы пытаетесь так сильно сэкономить память? Вы каким-то образом узнали, что эта часть кода потребляет слишком много памяти?
3. Не должны ли переменные bottom
MilRab()
иPrim()
использоватьszambig
?4. Это похоже на то, что кто-то с двумя миллиардами долларов в банке тратит час на то, чтобы торговаться из-за разницы в четыре доллара при покупке на миллион долларов. У вас уже есть два миллиарда байт доступного адресного пространства, и вы уже потратили миллион на стек. Теперь вы беспокоитесь о том, как эффективно справиться с четырьмя из этих байтов. У вас почти наверняка есть гораздо более важные причины для беспокойства.
5. @Эрик Липперт — К сожалению, так поступает большинство богатых людей…
Ответ №1:
Я не уверен на 100%, как это сделать.Net IL оптимизирует память, но в целом локальный тип «значение» (в отличие от «ссылочных» типов) сохраняется в стеке. Т.е. вы бы сохранили только ~ 4 байта, которые занимает целое число, не создавая его экземпляр, и только на время жизни этого одного вызова. Как только вы выходите из функции, стек очищается.
Структуры являются типами «значений» и также размещаются в стеке. Они резервируют память для всех других типов значений и ссылочных указателей по мере необходимости. Размер BigInteger одинаков независимо от того, является ли значение «Signed» истинным или ложным.
Я полагаю, мой реальный вопрос таков: почему одержимость памятью? В имеющемся у вас примере кода вам потребуется несколько десятков байт памяти, которые все будут освобождены при завершении работы метода.
Ответ №2:
Если бы вам удалось это сделать, в лучшем случае вы бы сэкономили 16 байт, которые BigInteger
занимают в 64-разрядном режиме (я думаю).
Я почти уверен, что об этом не стоит беспокоиться. В ситуациях, когда важны эти 16 байт:
- вероятно, вам не следует использовать .Net
- у вас, скорее всего, нет .Сеть доступна в любом случае