Правильным способом на данный момент является использование решения, рекомендованного @Roman Kuzmin в комментариях до @M. Dudley answer :
[IO.File]::WriteAllLines($filename, $content)
(я также немного сократил его, сняв ненужное пояснение пространства имен System
- по умолчанию оно будет заменено автоматически).
Программы на C ++ транслируются в ассемблерные программы во время генерации машинного кода из исходного кода. Было бы практически неправильно сказать, что сборка происходит медленнее, чем в C ++. Более того, сгенерированный двоичный код отличается от компилятора к компилятору. Таким образом, умный компилятор C ++ может создавать двоичный код, более оптимальный и эффективный, чем код тупого ассемблера.
Однако я считаю, что ваша методология профилирования имеет определенные недостатки. Ниже приведены общие рекомендации по профилированию:
Даже не смотря на сборку, наиболее очевидная причина заключается в том, что /= 2
, вероятно, оптимизирован как >>=1
, и многие процессоры работают очень быстро. Но даже если процессор не имеет операции сдвига, целочисленное деление быстрее, чем деление с плавающей запятой.
Редактировать: Ваш пробег может варьироваться в зависимости от выражения «целочисленное деление быстрее, чем деление с плавающей запятой» выше. Комментарии ниже показывают, что современные процессоры отдают предпочтение оптимизации деления fp над целочисленным делением. Так что, если кто-то ищет наиболее вероятную причину ускорения, о которой спрашивает этот поток, то компилятор, оптимизирующий /=2
как >>=1
, будет лучшим 1-м местом для поиска.
На не связанной ноте , если n
нечетно, выражение n*3+1
всегда будет четным. Так что проверять не нужно. Вы можете изменить эту ветвь на
{
n = (n*3+1) >> 1;
count += 2;
}
Таким образом, весь оператор будет тогда
if (n & 1)
{
n = (n*3 + 1) >> 1;
count += 2;
}
else
{
n >>= 1;
++count;
}