/* little gmp benchmark - compile with
   g++ -Wall -o gmpspeedtest gmpspeedtest
   and execute (./gmpspeedtest)
*/

#include <sys/time.h>
#include <stdio.h>
#include <gmp.h>

int main(void)
{
  int nRetval;
  timeval tvBefore, tvAfter;
  mpz_t mpzEins, mpzZwei;
  mpz_init(mpzEins);
  mpz_init(mpzZwei);
  mpz_set_str(mpzEins, "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz", 36);
  mpz_sqrt(mpzZwei, mpzEins);

  printf("gmp speed test / small benchmark\n");
  printf("mpzEins decimal: %d; mpzEins limbs: %d\nmpzEins: %s\n", mpz_sizeinbase(mpzEins, 10), (int)mpz_size(mpzEins), mpz_get_str(NULL, 10, mpzEins));
  printf("mpzZwei decimal: %d; mpzZwei limbs: %d\nmpzZwei: %s\n", mpz_sizeinbase(mpzZwei, 10), (int)mpz_size(mpzZwei), mpz_get_str(NULL, 10, mpzZwei));

  gettimeofday(&tvBefore, NULL);
  for(unsigned int i = 1; i < 10000; i++)
    {
      nRetval = mpz_divisible_ui_p(mpzEins, i);
    }
  gettimeofday(&tvAfter, NULL);
  printf("test1: mpz_divisible_ui_p: %d secs %d µsecs\n", (int)(tvAfter.tv_sec - tvBefore.tv_sec), (int)(tvAfter.tv_usec - tvBefore.tv_usec));

  gettimeofday(&tvBefore, NULL);
  for(unsigned int i = 1; i < 10000; i++)
    {
      nRetval = mpz_divisible_p(mpzEins, mpzZwei);
    }
  gettimeofday(&tvAfter, NULL);
  printf("test2: mpz_divisible_p: %d secs %d µsecs\n", (int)(tvAfter.tv_sec - tvBefore.tv_sec), (int)(tvAfter.tv_usec - tvBefore.tv_usec));

  gettimeofday(&tvBefore, NULL);
  for(unsigned int i = 1; i < 10000; i++)
    {
      mpz_sqrt(mpzZwei, mpzEins);
    }
  gettimeofday(&tvAfter, NULL);
  printf("test3: mpz_sqrt: %d secs %d µsecs\n", (int)(tvAfter.tv_sec - tvBefore.tv_sec), (int)(tvAfter.tv_usec - tvBefore.tv_usec));

  gettimeofday(&tvBefore, NULL);
  for(unsigned int i = 1; i < 10000; i++)
    {
      mpz_clear(mpzZwei);
      mpz_init_set_str(mpzZwei, "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz", 36);
    }
  gettimeofday(&tvAfter, NULL);
  printf("test4: mpz_clear & mpz_init_set_str: %d secs %d µsecs\n", (int)(tvAfter.tv_sec - tvBefore.tv_sec), (int)(tvAfter.tv_usec - tvBefore.tv_usec));

  return(0);
}
