Descubrí que la función BigInteger.ModPow en C# es muy lenta en comparación con la función BigInteger.modPow en Java. Esto me hace reacio a usar C# para implementar funciones que realicen exponenciación modular.
He escrito un programa de prueba para demostrarlo.
C#
static void Main(string[] args) { BigInteger num = BigInteger.Parse("444266014606582911577255360081280172978907874637194279031281180366057"); BigInteger m = 2; Console.WriteLine("Start multiply."); Stopwatch stopwatch = Stopwatch.StartNew(); for (int i = 3; i <= 200000; i++) m *= i; stopwatch.Stop(); Console.WriteLine(stopwatch.ElapsedMilliseconds); stopwatch.Reset(); Console.WriteLine("Start mod pow."); stopwatch.Start(); for (int i = 0; i < 10; i++) BigInteger.ModPow(3, m, num); stopwatch.Stop(); Console.WriteLine(stopwatch.ElapsedMilliseconds); }Un programa equivalente en Java
public static void main(String[] args) { BigInteger num = new BigInteger("444266014606582911577255360081280172978907874637194279031281180366057"); BigInteger m = BigInteger.TWO; System.out.println("Start multiply."); long startTime = System.currentTimeMillis(); for (int i = 3; i <= 200000; i++) m = m.multiply(BigInteger.valueOf(i)); System.out.println(System.currentTimeMillis() - startTime); System.out.println("Start mod pow."); startTime = System.currentTimeMillis(); for (int i = 0; i < 10; i++) BigInteger.valueOf(3).modPow(m, num); System.out.println(System.currentTimeMillis() - startTime); }El programa consta de 2 partes:
m .m mod num 10 veces.Puede cambiar los números o el conteo de bucles para intentar encontrar resultados diferentes.
Aquí hay un resultado de ejecución en mi computadora.
C#
Empieza a multiplicar. 19443 Inicie mod pow. 35292
Java
Empieza a multiplicar. 14668 Inicie mod pow. 3462
Muestra que la función BigInteger.ModPow en C# es unas 10 veces más lenta que la de Java. ¿Alguien sabe el motivo? ¿Es eso un error?