├── README.md ├── .gitignore ├── queen ├── bench.sh ├── queen.go ├── queen2.rs ├── queen3.rs ├── queen.rs ├── queen2.c ├── queen.c └── queen3.c └── LICENSE /README.md: -------------------------------------------------------------------------------- 1 | # LanguageMark 2 | Native Language Benchmark in Numerous Algorithms 3 | 4 | ## Eight Queens Problem 5 | 6 | | Name | C | Rust | Gap | 7 | |-|-|-|-| 8 | | Recursion | 571ms | 648ms | 13% | 9 | | Non-Recursion | 635ms | 667ms | 5% | 10 | 11 | Compiled with `clang 9` and `rustc 1.42`. 12 | 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Compiled Object files 5 | *.slo 6 | *.lo 7 | *.o 8 | *.obj 9 | 10 | # Precompiled Headers 11 | *.gch 12 | *.pch 13 | 14 | # Compiled Dynamic libraries 15 | *.so 16 | *.dylib 17 | *.dll 18 | 19 | # Fortran module files 20 | *.mod 21 | *.smod 22 | 23 | # Compiled Static libraries 24 | *.lai 25 | *.la 26 | *.a 27 | *.lib 28 | 29 | # Executables 30 | *.exe 31 | *.out 32 | *.app 33 | 34 | test/* 35 | -------------------------------------------------------------------------------- /queen/bench.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | CC="clang-9" 3 | 4 | echo "queen.c - non-recursion" 5 | $CC -O3 -mllvm -polly queen.c -o a.out -static && sleep 1 && ./a.out && rm -f a.out 6 | echo "queen.rs - non-recursion" 7 | rustc -O -C opt-level=3 queen.rs -o a.out && sleep 1 && ./a.out && rm -f a.out 8 | echo "queen.go - non-recursion" 9 | go build -o a.out queen.go && sleep 1 && ./a.out && rm -f a.out 10 | 11 | echo "queen2.c - recursion" 12 | $CC -O3 -mllvm -polly queen2.c -o a.out -static && sleep 1 && ./a.out && rm -f a.out 13 | echo "queen2.rs - recursion" 14 | rustc -O -C opt-level=3 queen2.rs -o a.out && sleep 1 && ./a.out && rm -f a.out 15 | 16 | echo "queen3.c - long time N=15" 17 | $CC -O3 -mllvm -polly queen3.c -o a.out -static && sleep 1 && ./a.out && rm -f a.out 18 | echo "queen3.rs - long time N=15" 19 | rustc -O -C opt-level=3 queen3.rs -o a.out && sleep 1 && ./a.out && rm -f a.out 20 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Linwei 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /queen/queen.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "log" 6 | "time" 7 | ) 8 | 9 | var cpuprofile = flag.String("cpuprofile", "", "write cpu profile to file") 10 | 11 | func main() { 12 | /* 13 | flag.Parse() 14 | if *cpuprofile != "" { 15 | f, err := os.Create(*cpuprofile) 16 | if err != nil { 17 | log.Fatal(err) 18 | } 19 | pprof.StartCPUProfile(f) 20 | defer pprof.StopCPUProfile() 21 | } 22 | */ 23 | 24 | queen() 25 | ts := time.Now() 26 | found := queen() 27 | log.Printf("found=%v, time=%v\n", found, time.Now().Sub(ts)) 28 | } 29 | 30 | const N = 13 31 | 32 | func check(q *[N]int, row int) int { 33 | if row == 0 { 34 | return 1 35 | } else { 36 | x0 := q[row] 37 | for y := 0; y < row; y++ { 38 | x := q[y] 39 | if x == x0 { 40 | return 0 41 | } else if x-x0 == row-y { 42 | return 0 43 | } else if x0-x == row-y { 44 | return 0 45 | } 46 | } 47 | } 48 | return 1 49 | } 50 | 51 | func queen() int { 52 | var q [N]int 53 | found := 0 54 | row := 0 55 | done := 0 56 | 57 | for done == 0 { 58 | if check(&q, row) > 0 { 59 | if row == N-1 { 60 | found++ 61 | } else { 62 | row++ 63 | q[row] = 0 64 | continue 65 | } 66 | } 67 | q[row] += 1 68 | for q[row] >= N { 69 | row-- 70 | if row >= 0 { 71 | q[row]++ 72 | } else { 73 | done = 1 74 | break 75 | } 76 | } 77 | } 78 | return found 79 | } 80 | -------------------------------------------------------------------------------- /queen/queen2.rs: -------------------------------------------------------------------------------- 1 | use std::time::{SystemTime, UNIX_EPOCH}; 2 | 3 | const N:i32 = 13; 4 | 5 | fn clock_realtime() -> i64 { 6 | let start = SystemTime::now(); 7 | let since_the_epoch = start.duration_since(UNIX_EPOCH).expect("Time went backwards"); 8 | return since_the_epoch.as_millis() as i64; 9 | } 10 | 11 | fn array_check(array: &[i32], row: i32) -> bool 12 | { 13 | if row == 0 { 14 | return true; 15 | } 16 | else { 17 | let x0 = array[row as usize]; 18 | for y in 0..row { 19 | let x = array[y as usize]; 20 | if x == x0 { 21 | return false; 22 | } 23 | else if x - x0 == row - y { 24 | return false; 25 | } 26 | else if x0 - x == row - y { 27 | return false; 28 | } 29 | } 30 | return true; 31 | } 32 | } 33 | 34 | fn search(array: &mut[i32], row: i32) -> i32 35 | { 36 | let mut found = 0; 37 | for i in 0..N { 38 | array[row as usize] = i; 39 | if array_check(array, row) { 40 | if row == N - 1 { 41 | found += 1; 42 | } else { 43 | found += search(array, row + 1); 44 | } 45 | } 46 | } 47 | return found; 48 | } 49 | 50 | fn queen() -> i32 51 | { 52 | let mut array = [0;N as usize]; 53 | return search(&mut array, 0); 54 | } 55 | 56 | fn main() 57 | { 58 | queen(); 59 | let ts = clock_realtime(); 60 | let found = queen(); 61 | let dt = clock_realtime() - ts; 62 | println!("found={} time={} ms", found, dt); 63 | } 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /queen/queen3.rs: -------------------------------------------------------------------------------- 1 | use std::time::{SystemTime, UNIX_EPOCH}; 2 | 3 | const N:i32 = 15; 4 | 5 | fn clock_realtime() -> i64 { 6 | let start = SystemTime::now(); 7 | let since_the_epoch = start.duration_since(UNIX_EPOCH).expect("Time went backwards"); 8 | return since_the_epoch.as_millis() as i64; 9 | } 10 | 11 | fn array_check(array: &[i32], row: i32) -> bool 12 | { 13 | if row == 0 { 14 | return true; 15 | } 16 | else { 17 | let x0 = array[row as usize]; 18 | for y in 0..row { 19 | let x = array[y as usize]; 20 | if x == x0 { 21 | return false; 22 | } 23 | else if (x - x0).abs() == row - y { 24 | return false; 25 | } 26 | } 27 | return true; 28 | } 29 | } 30 | 31 | 32 | fn queen() -> i32 33 | { 34 | let mut array = [0;N as usize]; 35 | let mut found = 0; 36 | let mut row = 0; 37 | let mut done = false; 38 | while done == false { 39 | if array_check(&array, row) { 40 | if row == N - 1 { 41 | found += 1; 42 | } else { 43 | row += 1; 44 | array[row as usize] = 0; 45 | continue; 46 | } 47 | } 48 | array[row as usize] += 1; 49 | while array[row as usize] >= N { 50 | row -= 1; 51 | if row >= 0 { 52 | array[row as usize] += 1; 53 | } else { 54 | done = true; 55 | break; 56 | } 57 | } 58 | } 59 | return found; 60 | } 61 | 62 | fn main() 63 | { 64 | queen(); 65 | let ts = clock_realtime(); 66 | let found = queen(); 67 | let dt = clock_realtime() - ts; 68 | println!("found={} time={} ms", found, dt); 69 | } 70 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /queen/queen.rs: -------------------------------------------------------------------------------- 1 | use std::time::{SystemTime, UNIX_EPOCH}; 2 | 3 | const N:i32 = 13; 4 | 5 | fn clock_realtime() -> i64 { 6 | let start = SystemTime::now(); 7 | let since_the_epoch = start.duration_since(UNIX_EPOCH).expect("Time went backwards"); 8 | return since_the_epoch.as_millis() as i64; 9 | } 10 | 11 | fn array_check(array: &[i32], row: i32) -> bool 12 | { 13 | if row == 0 { 14 | return true; 15 | } 16 | else { 17 | let x0 = array[row as usize]; 18 | for y in 0..row { 19 | let x = array[y as usize]; 20 | if x == x0 { 21 | return false; 22 | } 23 | else if x - x0 == row - y { 24 | return false; 25 | } 26 | else if x0 - x == row - y { 27 | return false; 28 | } 29 | } 30 | return true; 31 | } 32 | } 33 | 34 | 35 | fn queen() -> i32 36 | { 37 | let mut array = [0;N as usize]; 38 | let mut found = 0; 39 | let mut row = 0; 40 | let mut done = false; 41 | while done == false { 42 | if array_check(&array, row) { 43 | if row == N - 1 { 44 | found += 1; 45 | } else { 46 | row += 1; 47 | array[row as usize] = 0; 48 | continue; 49 | } 50 | } 51 | array[row as usize] += 1; 52 | while array[row as usize] >= N { 53 | row -= 1; 54 | if row >= 0 { 55 | array[row as usize] += 1; 56 | } else { 57 | done = true; 58 | break; 59 | } 60 | } 61 | } 62 | return found; 63 | } 64 | 65 | fn main() 66 | { 67 | queen(); 68 | let ts = clock_realtime(); 69 | let found = queen(); 70 | let dt = clock_realtime() - ts; 71 | println!("found={} time={} ms", found, dt); 72 | } 73 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /queen/queen2.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64) 6 | #include 7 | #else 8 | #include 9 | #ifndef __unix 10 | #define __unix 1 11 | #endif 12 | #endif 13 | 14 | int64_t clock_realtime(void) 15 | { 16 | int64_t sec, usec; 17 | #if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64) 18 | typedef void (WINAPI * GetSystemTime_t)(LPFILETIME); 19 | static GetSystemTime_t GetSystemTime_p = NULL; 20 | static int64_t epoch = 0; 21 | static volatile int inited = 0; 22 | LARGE_INTEGER ularge; 23 | FILETIME file_time; 24 | int64_t current; 25 | if (inited == 0) { 26 | ularge.HighPart = 0x019db1de; 27 | ularge.LowPart = 0xd53e8000; 28 | epoch = (int64_t)ularge.QuadPart; 29 | GetSystemTime_p = (GetSystemTime_t)GetProcAddress( 30 | GetModuleHandle(TEXT("kernel32.dll")), 31 | "GetSystemTimePreciseAsFileTime" 32 | ); 33 | inited = 1; 34 | } 35 | if (GetSystemTime_p == NULL) { 36 | GetSystemTimeAsFileTime(&file_time); 37 | } 38 | else { 39 | GetSystemTime_p(&file_time); 40 | } 41 | ularge.LowPart = file_time.dwLowDateTime; 42 | ularge.HighPart = file_time.dwHighDateTime; 43 | current = ((int64_t)ularge.QuadPart) - epoch; 44 | sec = (int64_t)(current / 10000000); 45 | usec = (int64_t)((current % 10000000) / 10); 46 | #else 47 | struct timeval time; 48 | gettimeofday(&time, NULL); 49 | sec = (int64_t)(time.tv_sec); 50 | usec = (int64_t)(time.tv_usec); 51 | #endif 52 | return (sec * 1000000) + (usec % 1000000); 53 | } 54 | 55 | 56 | #define N 13 57 | 58 | int check(int *q, int row) 59 | { 60 | if (row == 0) { 61 | return 1; 62 | } else { 63 | int y; 64 | int x0 = q[row]; 65 | for (y = 0; y < row; y++) { 66 | int x = q[y]; 67 | if (x == x0) 68 | return 0; 69 | else if (x - x0 == row - y) 70 | return 0; 71 | else if (x0 - x == row - y) 72 | return 0; 73 | } 74 | } 75 | return 1; 76 | } 77 | 78 | int search(int *array, int row) 79 | { 80 | int count = 0; 81 | int i; 82 | for (i = 0; i < N; i++) { 83 | array[row] = i; 84 | if (check(array, row)) { 85 | if (row == N - 1) { 86 | count++; 87 | } else { 88 | count += search(array, row + 1); 89 | } 90 | } 91 | } 92 | return count; 93 | } 94 | 95 | int queen() 96 | { 97 | int array[N] = {0}; 98 | return search(array, 0); 99 | } 100 | 101 | int main(void) 102 | { 103 | int found; 104 | queen(); 105 | int64_t ts = clock_realtime(); 106 | found = queen(); 107 | ts = clock_realtime() - ts; 108 | printf("found=%d time=%.3fms\n", found, ts * 0.001); 109 | return 0; 110 | } 111 | 112 | 113 | -------------------------------------------------------------------------------- /queen/queen.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64) 6 | #include 7 | #else 8 | #include 9 | #ifndef __unix 10 | #define __unix 1 11 | #endif 12 | #endif 13 | 14 | int64_t clock_realtime(void) 15 | { 16 | int64_t sec, usec; 17 | #if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64) 18 | typedef void (WINAPI * GetSystemTime_t)(LPFILETIME); 19 | static GetSystemTime_t GetSystemTime_p = NULL; 20 | static int64_t epoch = 0; 21 | static volatile int inited = 0; 22 | LARGE_INTEGER ularge; 23 | FILETIME file_time; 24 | int64_t current; 25 | if (inited == 0) { 26 | ularge.HighPart = 0x019db1de; 27 | ularge.LowPart = 0xd53e8000; 28 | epoch = (int64_t)ularge.QuadPart; 29 | GetSystemTime_p = (GetSystemTime_t)GetProcAddress( 30 | GetModuleHandle(TEXT("kernel32.dll")), 31 | "GetSystemTimePreciseAsFileTime" 32 | ); 33 | inited = 1; 34 | } 35 | if (GetSystemTime_p == NULL) { 36 | GetSystemTimeAsFileTime(&file_time); 37 | } 38 | else { 39 | GetSystemTime_p(&file_time); 40 | } 41 | ularge.LowPart = file_time.dwLowDateTime; 42 | ularge.HighPart = file_time.dwHighDateTime; 43 | current = ((int64_t)ularge.QuadPart) - epoch; 44 | sec = (int64_t)(current / 10000000); 45 | usec = (int64_t)((current % 10000000) / 10); 46 | #else 47 | struct timeval time; 48 | gettimeofday(&time, NULL); 49 | sec = (int64_t)(time.tv_sec); 50 | usec = (int64_t)(time.tv_usec); 51 | #endif 52 | return (sec * 1000000) + (usec % 1000000); 53 | } 54 | 55 | 56 | #define N 13 57 | 58 | int check(int *q, int row) 59 | { 60 | if (row == 0) { 61 | return 1; 62 | } else { 63 | int y; 64 | int x0 = q[row]; 65 | for (y = 0; y < row; y++) { 66 | int x = q[y]; 67 | if (x == x0) 68 | return 0; 69 | else if (x - x0 == row - y) 70 | return 0; 71 | else if (x0 - x == row - y) 72 | return 0; 73 | } 74 | } 75 | return 1; 76 | } 77 | 78 | int queen() 79 | { 80 | int q[N] = {0}; 81 | int found = 0; 82 | int row = 0; 83 | int done = 0; 84 | while (done == 0) { 85 | if (check(q, row)) { 86 | if (row == N - 1) { 87 | found++; 88 | } else { 89 | row++; 90 | q[row] = 0; 91 | continue; 92 | } 93 | } 94 | q[row] += 1; 95 | while (q[row] >= N) { 96 | row--; 97 | if (row >= 0) { 98 | q[row]++; 99 | } else { 100 | done = 1; 101 | break; 102 | } 103 | } 104 | } 105 | return found; 106 | } 107 | 108 | int main(void) 109 | { 110 | int found; 111 | queen(); 112 | int64_t ts = clock_realtime(); 113 | found = queen(); 114 | ts = clock_realtime() - ts; 115 | printf("found=%d time=%.3fms\n", found, ts * 0.001); 116 | return 0; 117 | } 118 | 119 | 120 | -------------------------------------------------------------------------------- /queen/queen3.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64) 6 | #include 7 | #else 8 | #include 9 | #include 10 | #include 11 | #include 12 | #ifndef __unix 13 | #define __unix 1 14 | #endif 15 | #endif 16 | 17 | int64_t clock_realtime(void) 18 | { 19 | int64_t sec, usec; 20 | #if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64) 21 | typedef void (WINAPI * GetSystemTime_t)(LPFILETIME); 22 | static GetSystemTime_t GetSystemTime_p = NULL; 23 | static int64_t epoch = 0; 24 | static volatile int inited = 0; 25 | LARGE_INTEGER ularge; 26 | FILETIME file_time; 27 | int64_t current; 28 | if (inited == 0) { 29 | ularge.HighPart = 0x019db1de; 30 | ularge.LowPart = 0xd53e8000; 31 | epoch = (int64_t)ularge.QuadPart; 32 | GetSystemTime_p = (GetSystemTime_t)GetProcAddress( 33 | GetModuleHandle(TEXT("kernel32.dll")), 34 | "GetSystemTimePreciseAsFileTime" 35 | ); 36 | inited = 1; 37 | } 38 | if (GetSystemTime_p == NULL) { 39 | GetSystemTimeAsFileTime(&file_time); 40 | } 41 | else { 42 | GetSystemTime_p(&file_time); 43 | } 44 | ularge.LowPart = file_time.dwLowDateTime; 45 | ularge.HighPart = file_time.dwHighDateTime; 46 | current = ((int64_t)ularge.QuadPart) - epoch; 47 | sec = (int64_t)(current / 10000000); 48 | usec = (int64_t)((current % 10000000) / 10); 49 | #else 50 | struct timeval time; 51 | gettimeofday(&time, NULL); 52 | sec = (int64_t)(time.tv_sec); 53 | usec = (int64_t)(time.tv_usec); 54 | #endif 55 | return (sec * 1000000) + (usec % 1000000); 56 | } 57 | 58 | void isleep(unsigned long millisecond) 59 | { 60 | #ifdef __unix /* usleep( time * 1000 ); */ 61 | #if 0 62 | struct timespec ts; 63 | ts.tv_sec = (time_t)(millisecond / 1000); 64 | ts.tv_nsec = (long)((millisecond % 1000) * 1000000); 65 | nanosleep(&ts, NULL); 66 | #else 67 | usleep((millisecond << 10) - (millisecond << 4) - (millisecond << 3)); 68 | #endif 69 | #elif defined(_WIN32) 70 | Sleep(millisecond); 71 | #endif 72 | } 73 | 74 | 75 | #define N 15 76 | 77 | static inline int abs(int x) { 78 | return (x < 0)? (-x) : x; 79 | } 80 | 81 | int check(int *q, int row) 82 | { 83 | if (row == 0) { 84 | return 1; 85 | } else { 86 | int y; 87 | int x0 = q[row]; 88 | for (y = 0; y < row; y++) { 89 | int x = q[y]; 90 | if (x == x0) 91 | return 0; 92 | else if (abs(x - x0) == row - y) 93 | return 0; 94 | } 95 | } 96 | return 1; 97 | } 98 | 99 | int queen() 100 | { 101 | int q[N] = {0}; 102 | int found = 0; 103 | int row = 0; 104 | int done = 0; 105 | while (done == 0) { 106 | if (check(q, row)) { 107 | if (row == N - 1) { 108 | found++; 109 | } else { 110 | row++; 111 | q[row] = 0; 112 | continue; 113 | } 114 | } 115 | q[row] += 1; 116 | while (q[row] >= N) { 117 | row--; 118 | if (row >= 0) { 119 | q[row]++; 120 | } else { 121 | done = 1; 122 | break; 123 | } 124 | } 125 | } 126 | return found; 127 | } 128 | 129 | int main(void) 130 | { 131 | clock_realtime(); 132 | { 133 | int found; 134 | queen(); 135 | isleep(1000); 136 | int64_t ts = clock_realtime(); 137 | found = queen(); 138 | ts = clock_realtime() - ts; 139 | printf("found=%d time=%.3fms\n", found, ts * 0.001); 140 | } 141 | return 0; 142 | } 143 | 144 | 145 | --------------------------------------------------------------------------------