C # BigInteger и int Как сохранить память?

#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 байт:

  1. вероятно, вам не следует использовать .Net
  2. у вас, скорее всего, нет .Сеть доступна в любом случае