c # Почему быстрее объявлять и выделять локальный итератор, а не использовать глобальный? - PullRequest
1 голос
/ 03 апреля 2019

Я новичок в C #, я программировал в течение года, но только время от времени, поэтому, пожалуйста, будьте терпеливы со мной.

Я запустил тестовую установку со следующими - оченьмного базового - код:

namespace SpeedTest
{
    public class TestClass
    {
        internal struct testStruct {
            internal int iterator;
        }

        private testStruct _tS;
        private byte[] _bytes;


        public TestClass(string s)
        {
            _tS = new testStruct();
            _tS.iterator = 0;
            _bytes = File.ReadAllBytes(s);
        }

        public void runWithGlobalVar () 
        {
            while(_tS.iterator != _bytes.Length)
                _tS.iterator++;
        }

        public void runWithLocalVar() 
        {
            int i = 0;
            while (i != _bytes.Length)
                i++;
        }

        public void runWithTwoLocalVar() 
        {
            int i = 0;
            int y = _bytes.Length;
            while (i != y)
                i++;
        }
    }
}

Если я протестирую это на скорости с довольно большими файлами (> 15 МБ, только для целей тестирования, я не выделю эту сумму в байтовый массив без некоторых проверок на практике)Я наблюдаю следующее поведение:

  • Самый быстрый - это runWithTwoLocalVar ().
  • Закрыть, но второй самый быстрый - это runWithLocalVar ()
  • Самый медленный - это runWithGlobalVar ().Это значительно медленнее, чем другие два (занимает около 135% времени, необходимого для одного из других методов).

Может кто-нибудь объяснить мне внутреннюю работу этого?Что происходит с памятью и почему runWithGlobalVar () занимает так много времени?

Редактировать: Пожалуйста, имейте в виду, что это тестовая установка, и я не вижу смысла делать это на практике.Просто я видел, как это делается в очень сложном коде по разным причинам, иногда даже в исходном коде c # от Microsoft.

1 Ответ

0 голосов
/ 03 апреля 2019

Вам нужно проверить, что structs делает по сравнению с classes в C #. ( здесь для вступления и особенно в чем разница между стеком и кучей).

Ваша функция runWithTwoLocalVars использует целые числа, которые хранятся прямо здесь, в стеке функций : повторный доступ к ним не требует больших затрат (мы говорим, что нет накладных расходов).

С другой стороны, ваша «глобальная» версия должна идти и извлекать данные, хранящиеся в структуре, из того места, где они хранятся в памяти: это имеет некоторые накладные расходы (по крайней мере, нужно «следовать указателю», обозначая место, где экземпляр структуры находится в памяти, как для _ts, так и для bytes)

...