Skip to content

Instantly share code, notes, and snippets.

@regexident
Created March 12, 2020 13:35
Show Gist options
  • Save regexident/7a40afd5ca23170ae462deab74cea4d6 to your computer and use it in GitHub Desktop.
Save regexident/7a40afd5ca23170ae462deab74cea4d6 to your computer and use it in GitHub Desktop.
Performance comparison
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <sys/time.h>
double get_one_by_pi(int iterations) {
double ak = 6.0 - 4 * sqrt(2);
double yk = sqrt(2) - 1.0;
double ak1;
double yk1;
for (int i = 0; i < iterations; i++) {
yk1 =
(1 - pow(1 - yk * yk * yk * yk, 0.25)) /
(1 + pow(1 - yk * yk * yk * yk, 0.25));
ak1 =
ak * pow(1 + yk1, 4) -
pow(2, 2 * i + 3) * yk1 * (1 + yk1 + yk1 * yk1);
yk = yk1;
ak = ak1;
}
return ak;
}
int64_t get_current_millis() {
struct timeval time;
gettimeofday(&time, NULL);
int64_t s1 = (int64_t)(time.tv_sec) * 1000;
int64_t s2 = (time.tv_usec / 1000);
return s1 + s2;
}
const int max_iterations = 10000;
int main(int argc, const char * argv[]) {
if (argc != 3) {
const char *executable = argv[0];
printf("USAGE: %s ITERATIONS DECIMALS\n", executable);
exit(1);
}
const int iterations = atoi(argv[1]);
const int decimals = atoi(argv[2]);
double sum = 0.0;
double *benchmarks = calloc(iterations, sizeof(double));
printf("Iterations: %d\n", iterations);
printf("Decimals: %d\n", decimals);
printf("\n");
printf("Running benchmarks...\n");
for (int i = 0; i < iterations; i++) {
long startTime = get_current_millis();
sum += get_one_by_pi(decimals);
long endTime = get_current_millis();
double iterTime = ((double)endTime - startTime);
benchmarks[i] = iterTime;
}
printf("\n");
double factor = 1.0 / (double)iterations;
double mean = 0.0;
for (int i = 0; i < iterations; i++) {
mean += benchmarks[i] * factor;
}
double variance = 0.0;
for (int i = 0; i < iterations; i++) {
double delta = benchmarks[i] - mean;
variance += delta * delta * factor;
}
printf("Mean: %f ms\n", mean);
printf("Variance: %f ms\n", variance);
printf("\n");
return (int)sum;
}
fn get_one_by_pi(iterations: usize) -> f64 {
let mut ak: f64 = 6.0 - 4.0 * 2.0f64.sqrt();
let mut yk: f64 = 2.0f64.sqrt() - 1.0;
let mut ak1: f64;
let mut yk1: f64;
let mut temp2: f64;
let mut temp1: f64;
let mut i: f64 = 0.0;
let iter = iterations as f64;
while i < iter {
i = i + 1.0;
yk1 = (1.0 - (1.0 - yk * yk * yk * yk).powf(0.25))
/ (1.0 + (1.0 - yk * yk * yk * yk).powf(0.25));
temp2 = 2.0f64.powf(2.0 * i + 3.0);
temp1 = (1.0 + yk1 + yk1 * yk1) * temp2 * yk1;
ak1 = ak * (1.0 + yk1).powf(4.0) - temp1;
yk = yk1;
ak = ak1;
}
return ak;
}
fn get_current_millis() -> isize {
use std::time::{SystemTime, UNIX_EPOCH};
SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_millis() as isize
}
fn main() {
if std::env::args().len() != 3 {
let executable = std::env::args().nth(0).unwrap();
println!("USAGE: {} ITERATIONS DECIMALS\n", executable);
std::process::exit(1);
}
let iterations: usize = std::env::args().nth(1).unwrap().parse().unwrap();
let decimals: usize = std::env::args().nth(2).unwrap().parse().unwrap();
let mut sum = 0.0;
let mut benchmarks: Vec<f64> = vec![0.0; iterations];
println!("Iterations: {}", iterations);
println!("Decimals: {}", decimals);
println!();
println!("Running benchmarks...");
for i in 0..iterations {
let start_time = get_current_millis();
sum += get_one_by_pi(decimals);
let end_time = get_current_millis();
let iter_time = (end_time - start_time) as f64;
benchmarks[i] = iter_time;
}
let factor = 1.0 / (iterations as f64);
let average = benchmarks
.iter()
.fold(0.0, |sum, elem| sum + (elem * factor));
let variance = benchmarks.iter().fold(0.0, |sum, elem| {
let delta = elem - average;
sum + (delta * delta * factor)
});
println!();
println!("Average: {} ms", average);
println!("Variance: {} ms", variance);
println!();
std::process::exit(sum as i32);
}
ITERATIONS=1000
DECIMALS=1000000
echo ""
echo ""
echo "C:"
./benchmark_c $ITERATIONS $DECIMALS
echo ""
echo ""
echo "C (fixed):"
./benchmark_c_fixed $ITERATIONS $DECIMALS
echo ""
echo ""
echo "Swift:"
./benchmark_swift $ITERATIONS $DECIMALS
echo ""
echo ""
echo "Rust:"
./benchmark_rust $ITERATIONS $DECIMALS
import Foundation
func getOneByPi(iterations: Int) -> Double {
var ak: Double = 6.0 - 4.0 * sqrt(2.0)
var yk: Double = sqrt(2.0) - 1.0
var ak1: Double
var yk1: Double
var temp2: Double
var temp1: Double
var i: Double = 0.0;
let iter = Double(iterations)
while i < iter {
i = i + 1.0
let n = 1.0 - pow(1.0 - yk * yk * yk * yk, 0.25)
let d = 1.0 + pow(1.0 - yk * yk * yk * yk, 0.25)
yk1 = n / d;
temp2 = pow(2.0, 2.0 * i + 3.0)
temp1 = (1.0 + yk1 + yk1 * yk1) * temp2 * yk1
ak1 = ak * pow(1.0 + yk1, 4.0) - temp1
yk = yk1;
ak = ak1;
}
return ak
}
func getCurrentMillis() -> Int64{
return Int64(NSDate().timeIntervalSince1970 * 1000)
}
if (CommandLine.arguments.count != 3) {
let executable = CommandLine.arguments[0];
print("USAGE: \(executable) ITERATIONS DECIMALS");
exit(1);
}
let iterations = Int(CommandLine.arguments[1])!
let decimals = Int(CommandLine.arguments[2])!
var sum = 0.0
var benchmarks: [Double] = Array(repeating: 0.0, count: iterations)
print("Iterations: \(iterations)")
print("Decimals: \(decimals)")
print()
print("Running benchmarks...")
for i in 0..<iterations {
let startTime = getCurrentMillis()
sum += getOneByPi(iterations: decimals)
let endTime = getCurrentMillis()
let iterTime = Double(endTime - startTime)
benchmarks[i] = iterTime
}
print()
let factor = 1.0 / Double(iterations)
let mean = benchmarks.reduce(0.0) {
$0 + ($1 * factor)
}
let variance = benchmarks.reduce(0.0) {
let delta = $1 - mean
return $0 + (delta * delta * factor)
}
print("Mean: \(mean) ms")
print("Variance: \(variance) ms")
print()
exit(Int32(sum))
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <sys/time.h>
double get_one_by_pi(int iterations) {
double ak = 6.0 - 4.0 * sqrt(2.0);
double yk = sqrt(2.0) - 1.0;
double ak1;
double yk1;
double i;
double iter = (double)iterations;
for (i = 0.0; i < iter; i += 1.0) {
yk1 =
(1.0 - pow(1.0 - yk * yk * yk * yk, 0.25)) /
(1.0 + pow(1.0 - yk * yk * yk * yk, 0.25));
ak1 =
ak * pow(1.0 + yk1, 4.0) -
pow(2.0, 2.0 * i + 3.0) * yk1 * (1.0 + yk1 + yk1 * yk1);
yk = yk1;
ak = ak1;
}
return ak;
}
int64_t get_current_millis() {
struct timeval time;
gettimeofday(&time, NULL);
int64_t s1 = (int64_t)(time.tv_sec) * 1000;
int64_t s2 = (time.tv_usec / 1000);
return s1 + s2;
}
const int max_iterations = 10000;
int main(int argc, const char * argv[]) {
if (argc != 3) {
const char *executable = argv[0];
printf("USAGE: %s ITERATIONS DECIMALS\n", executable);
exit(1);
}
const int iterations = atoi(argv[1]);
const int decimals = atoi(argv[2]);
double sum = 0.0;
double *benchmarks = calloc(iterations, sizeof(double));
printf("Iterations: %d\n", iterations);
printf("Decimals: %d\n", decimals);
printf("\n");
printf("Running benchmarks...\n");
for (int i = 0; i < iterations; i++) {
long startTime = get_current_millis();
sum += get_one_by_pi(decimals);
long endTime = get_current_millis();
double iterTime = ((double)endTime - startTime);
benchmarks[i] = iterTime;
}
printf("\n");
double factor = 1.0 / (double)iterations;
double mean = 0.0;
for (int i = 0; i < iterations; i++) {
mean += benchmarks[i] * factor;
}
double variance = 0.0;
for (int i = 0; i < iterations; i++) {
double delta = benchmarks[i] - mean;
variance += delta * delta * factor;
}
printf("Mean: %f ms\n", mean);
printf("Variance: %f ms\n", variance);
printf("\n");
return (int)sum;
}
Iterations: 1000
Decimals: 1000000
C:
Mean: 10.124000 ms
Variance: 0.236624 ms
C (fixed):
Mean: 9.951000 ms
Variance: 0.438599 ms
Swift:
Mean: 10.008999999999908 ms
Variance: 0.3549189999999963 ms
Rust:
Average: 10.008999999999903 ms
Variance: 0.400918999999994 ms
MacBook Pro (15-inch, 2018)
2.6 GHz 6-Core Intel Core i7
macOS 10.15.4 Beta (19E250c)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment