Вычисление количества символов в переменной (C#)
Какой из вариантов вычисления количества символов в числе эффективнее.
через перебор
for(ulong t = degre_of; t > 0; t = t / 10)
{
deg_lenght++;
}
или через длину строки
deg_lenght = degre_of.ToString().Length;
Ответы (1 шт):
Зачем гадать, давайте протестируем.
Ставим Benchmark.NET, пишем вот такой тест. Так же добавлю метод с логарифмом, который предложил @demonplus в комментариях.
class Program
{
static void Main(string[] args)
{
var summary = BenchmarkRunner.Run<MyBenchmark>();
Console.ReadKey();
}
}
[MemoryDiagnoser]
public class MyBenchmark
{
[Benchmark]
public int MathTest()
{
int total = 0;
for (uint number = 1; number <= 10000000; number++)
{
int length = 0;
for (uint t = number; t > 0; t /= 10)
{
length++;
}
total += length;
}
return total;
}
[Benchmark]
public int StringTest()
{
int total = 0;
for (uint number = 1; number <= 10000000; number++)
{
total += number.ToString().Length;
}
return total;
}
[Benchmark]
public int Log10Test()
{
int total = 0;
for (uint number = 1; number <= 10000000; number++)
{
total += (int)Math.Log10(number) + 1;
}
return total;
}
}
Считаем сумму длин всех чисел от 1 до миллиона. Если вывести в консоль, результат всех методов будет одинаковый.
Console.WriteLine(MathTest());
Console.WriteLine(StringTest());
Console.WriteLine(Log10Test());
68888897
68888897
68888897
Запускаем тест производительности
BenchmarkDotNet=v0.12.1, OS=Windows 10.0.19042
Intel Core i7-4700HQ CPU 2.40GHz (Haswell), 1 CPU, 8 logical and 4 physical cores
.NET Core SDK=5.0.103
[Host] : .NET Core 3.1.12 (CoreCLR 4.700.21.6504, CoreFX 4.700.21.6905), X64 RyuJIT
DefaultJob : .NET Core 3.1.12 (CoreCLR 4.700.21.6504, CoreFX 4.700.21.6905), X64 RyuJIT
| Method | Mean | Error | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
|----------- |----------:|---------:|---------:|------------:|------:|------:|------------:|
| MathTest | 57.64 ms | 0.391 ms | 0.347 ms | - | - | - | 528 B |
| StringTest | 356.61 ms | 3.732 ms | 3.309 ms | 127000.0000 | - | - | 399199720 B |
| Log10Test | 87.39 ms | 0.628 ms | 0.524 ms | - | - | - | 95 B |
И видим, что метод с использованием строки не только в 7 раз медленнее, чем метод с циклом, но еще и скушал дополнительно 400 кб памяти для работы. И цикл все-таки оказался быстрее десятичного логарифма.
Кстати, в методе с циклом есть баг, который я просто обошел в тестах, если число равно 0, то метод со строкой вернет 1, а метод с циклом - 0. Но вы уже наверняка поняли, как это исправить.