#include <stdio.h> #include <stdlib.h> #include <memory.h> #include <locale.h> #include <stdint.h> #include <time.h> #include <sys/time.h> void insersion_sort(unsigned array[], unsigned length); #define swap(a, b) do {unsigned tmp; tmp = *(b); *(b) = *(a); *(a) = tmp;} while (0) typedef unsigned int aho_type_t; void insersion_sort2(aho_type_t* au_data, size_t u_n); aho_type_t* aho_malloc_random_data(size_t u_n); aho_type_t* aho_malloc_clone_data(aho_type_t const* au_data, size_t u_n); aho_type_t const* aho_check_seq1(aho_type_t const* au_data, size_t u_n); aho_type_t const* aho_check_seq2(aho_type_t const* au_random_data, aho_type_t const* au_sorted_data, size_t u_n); uint32_t aho_xorshift_u32(void); int32_t aho_xorshift_i32(void); aho_type_t const* aho_bsearch_upper_bound_p(aho_type_t const* au_data_s, aho_type_t const* au_data_e, aho_type_t value); double aho_sec_count(void); int aho_qcomp(const void *r, const void *l); /* 32bit擬似乱数生成 */ static uint32_t u_seed = 2463534242; uint32_t aho_xorshift_u32(void) { u_seed = u_seed ^ (u_seed << 13); u_seed = u_seed ^ (u_seed >> 17); return (u_seed = u_seed ^ (u_seed << 15)); } int32_t aho_xorshift_i32(void) { u_seed = u_seed ^ (u_seed << 13); u_seed = u_seed ^ (u_seed >> 17); return (u_seed = u_seed ^ (u_seed << 15)); } /* n個の乱数列生成 */ aho_type_t* aho_malloc_random_data(size_t u_n) { aho_type_t* pu_data = au_data; aho_type_t* pu_end_of_data = au_data + u_n; for ( ; pu_data < pu_end_of_data; ++pu_data) { *pu_data = aho_xorshift_u32(); } return au_data; } aho_type_t* aho_malloc_clone_data(aho_type_t const* au_data, size_t u_n) { return pu_data; } /* 列が整列されているかチェック NULL:チェックOK NULL以外:整列された列のペケの要素のアドレス */ aho_type_t const* aho_check_seq1(aho_type_t const* au_data, size_t u_n) { aho_type_t const* cu_data = au_data; aho_type_t const* cu_end_of_data = au_data + u_n - 1; for (; cu_data < cu_end_of_data; ++cu_data) { if (*cu_data > *(cu_data + 1)) { fprintf(stderr, "【診断結果】:列(=[%zu])の値(=%u)と列(=[%zu])の値(=%u)の大小関係が適切ではありません\n", (size_t)(cu_data - au_data), *cu_data, (size_t)((cu_data + 1) - au_data), *(cu_data + 1)); return cu_data + 1; } } return NULL; } /* 昇順ソートされた列から先頭の値を検索(値は重複している) */ aho_type_t const* aho_bsearch_upper_bound_p(aho_type_t const* au_data_s, aho_type_t const* au_data_e, aho_type_t value) { aho_type_t const* cu_data_s = au_data_s; aho_type_t const* cu_data_e = au_data_e; aho_type_t const* cu_data_m = NULL; while (cu_data_s < cu_data_e) { cu_data_m = cu_data_s + ((cu_data_e - cu_data_s) >> 1); if (*cu_data_m < value) { cu_data_s = cu_data_m + 1; } else { cu_data_e = cu_data_m; } } return (cu_data_m != NULL && cu_data_e == cu_data_s && *cu_data_s == value) ? cu_data_s : NULL; } #define BITS_TO_BYTES(bits) ((size_t)(((((bits) - 1) >> 3) + 1) * sizeof(char))) #define BIT_POS_TO_BYTE_POS(bit_pos) ((size_t)((bit_pos) >> 3)) #define BIT_POS_TO_BYTE_BIT_POS(bit_pos) ((bit_pos) & 0x7) #define GET_BIT(byte_array,bit_pos) ((unsigned int)(((byte_array)[BIT_POS_TO_BYTE_POS(bit_pos)] >> BIT_POS_TO_BYTE_BIT_POS(bit_pos)) & 0x01)) #define SET_BIT_ON(byte_array,bit_pos) ((unsigned int)((byte_array)[BIT_POS_TO_BYTE_POS(bit_pos)] |= (0x01 << BIT_POS_TO_BYTE_BIT_POS(bit_pos)))) /* 入力の列の値が整列された列に全て含まれているかチェック(当然、値は重複していることがある) NULL:チェックOK NULL以外:入力された列のペケの要素のアドレス */ aho_type_t const* aho_check_seq2(aho_type_t const* au_random_data, aho_type_t const* au_sorted_data, size_t u_n) { aho_type_t const* cu_random_data = au_random_data; aho_type_t const* cu_end_of_random_data = au_random_data + u_n; aho_type_t const* cu_sorted_data; aho_type_t const* cu_end_of_sorted_data = au_sorted_data + u_n; size_t u_sorted_data_index; unsigned char* au_byte_array; size_t u_byte_size; if (u_n == 0) { return NULL; } u_byte_size = BITS_TO_BYTES(u_n); for (; cu_random_data < cu_end_of_random_data; ++cu_random_data) { cu_sorted_data = aho_bsearch_upper_bound_p(au_sorted_data, cu_end_of_sorted_data, *cu_random_data); if (cu_sorted_data == NULL) { fprintf(stderr, "【診断結果】:入力の列(=[%zu])の値(=%u)がソートされた列にありません(1)\n", (size_t)(cu_random_data - au_random_data), *cu_random_data); return cu_random_data; // ソートされた列に値がないからペケ } /* チェック済の要素かチェックし、チェック済でない要素を特定しチェック済にする */ u_sorted_data_index = cu_sorted_data - au_sorted_data; if (!GET_BIT(au_byte_array, u_sorted_data_index)) { SET_BIT_ON(au_byte_array, u_sorted_data_index); // チェック済にする continue; } ++cu_sorted_data; ++u_sorted_data_index; for (; cu_sorted_data < cu_end_of_sorted_data; ++u_sorted_data_index, ++cu_sorted_data) { if (*cu_sorted_data != *cu_random_data) { fprintf(stderr, "【診断結果】:入力の列(=[%zu])の値(=%u)がソートされた列にありません(2)\n", (size_t)(cu_random_data - au_random_data), *cu_random_data); return cu_random_data; // 重複値の余分がもうないからペケ } if (!GET_BIT(au_byte_array, u_sorted_data_index)) { SET_BIT_ON(au_byte_array, u_sorted_data_index); // チェック済にする break; } } } return NULL; } double aho_sec_count(void) { struct timeval tv; gettimeofday(&tv, NULL); return (double)tv.tv_sec + ((double)tv.tv_usec / 1000000.0); } int aho_qcomp(const void *l, const void *r) { return *(aho_type_t*)l > *(aho_type_t*)r ? 1 : (*(aho_type_t*)l < *(aho_type_t*)r ? -1 : 0); } int main(int argc, char **argv) { size_t u_n; aho_type_t* au_data; aho_type_t* au_sort; aho_type_t* au_sort2; aho_type_t* au_qsort; double rs; double re; clock_t us; clock_t ue; for (size_t i = 0; i < 17; ++i) { u_n = (size_t)0x1 << i; au_data = aho_malloc_random_data(u_n); au_sort = aho_malloc_clone_data(au_data, u_n); au_sort2 = aho_malloc_clone_data(au_data, u_n); au_qsort = aho_malloc_clone_data(au_data, u_n); rs = aho_sec_count(); insersion_sort(au_sort, u_n); re = aho_sec_count(); fprintf(stdout, ",%.06lf,%.06lf,%.06lf,%.06lf\n", re - rs, (double)(ue - us) / CLOCKS_PER_SEC, (re - rs) / u_n * 100000, (double)(ue - us) / CLOCKS_PER_SEC / u_n * 100000); rs = aho_sec_count(); re = aho_sec_count(); fprintf(stdout, ",%.06lf,%.06lf,%.06lf,%.06lf\n", re - rs, (double)(ue - us) / CLOCKS_PER_SEC, (re - rs) / u_n * 100000, (double)(ue - us) / CLOCKS_PER_SEC / u_n * 100000); rs = aho_sec_count(); insersion_sort2(au_sort2, u_n); re = aho_sec_count(); fprintf(stdout, ",%.06lf,%.06lf,%.06lf,%.06lf\n", re - rs, (double)(ue - us) / CLOCKS_PER_SEC, (re - rs) / u_n * 100000, (double)(ue - us) / CLOCKS_PER_SEC / u_n * 100000); rs = aho_sec_count(); re = aho_sec_count(); fprintf(stdout, ",%.06lf,%.06lf,%.06lf,%.06lf\n", re - rs, (double)(ue - us) / CLOCKS_PER_SEC, (re - rs) / u_n * 100000, (double)(ue - us) / CLOCKS_PER_SEC / u_n * 100000); rs = aho_sec_count(); re = aho_sec_count(); fprintf(stdout, ",%.06lf,%.06lf,%.06lf,%.06lf\n", re - rs, (double)(ue - us) / CLOCKS_PER_SEC, (re - rs) / u_n * 100000, (double)(ue - us) / CLOCKS_PER_SEC / u_n * 100000); rs = aho_sec_count(); re = aho_sec_count(); fprintf(stdout, ",%.06lf,%.06lf,%.06lf,%.06lf\n", re - rs, (double)(ue - us) / CLOCKS_PER_SEC, (re - rs) / u_n * 100000, (double)(ue - us) / CLOCKS_PER_SEC / u_n * 100000); } return 0; } void insersion_sort(unsigned array[], unsigned length) { register unsigned *start = &array[0]; register unsigned *sorted = start; register unsigned *end = &array[length - 1]; while (sorted < end) { register unsigned *crnt = sorted + 1; while (crnt > start && *crnt < *(crnt - 1)) { swap(crnt, crnt - 1); crnt--; } sorted++; } } void insersion_sort2(aho_type_t* au_A, size_t n_A_length) { /* ① i ← 1 ① while i < length(A) ② x ← A[i] ③ j ← i - 1 ④ while j >= 0 and A[j] > x ⑤ A[j+1] ← A[j] ④ j ← j - 1 ⑥ end while ⑦ A[j+1] ← x ① i ← i + 1 ① end while */ const aho_type_t const* cu_end_of_data = au_A + n_A_length; for (aho_type_t* au_i = au_A + 1; au_i < cu_end_of_data; ++au_i) { // ① aho_type_t u_x = *au_i; // ② aho_type_t* au_j = au_i - 1; // ③ for ( ; au_j >= au_A && *au_j >= u_x; --au_j) { // ④ *(au_j + 1) = *(au_j); // ⑤ } // ⑥ *(au_j + 1) = u_x; // ⑦ } }
Standard input is empty
sort,1,0.000002,0.000000,0.214577,0.000000 diag,1,0.000002,0.000001,0.214577,0.100000 sort2,1,0.000001,0.000000,0.095367,0.000000 diag,1,0.000000,0.000000,0.000000,0.000000 qsort,1,0.000001,0.000000,0.095367,0.000000 diag,1,0.000000,0.000000,0.000000,0.000000 sort,2,0.000001,0.000000,0.047684,0.000000 diag,2,0.000000,0.000001,0.000000,0.050000 sort2,2,0.000000,0.000000,0.000000,0.000000 diag,2,0.000000,0.000000,0.000000,0.000000 qsort,2,0.000000,0.000000,0.000000,0.000000 diag,2,0.000001,0.000000,0.059605,0.000000 sort,4,0.000000,0.000001,0.000000,0.025000 diag,4,0.000000,0.000000,0.000000,0.000000 sort2,4,0.000000,0.000000,0.000000,0.000000 diag,4,0.000000,0.000000,0.000000,0.000000 qsort,4,0.000001,0.000000,0.023842,0.000000 diag,4,0.000001,0.000000,0.023842,0.000000 sort,8,0.000000,0.000000,0.000000,0.000000 diag,8,0.000000,0.000000,0.000000,0.000000 sort2,8,0.000000,0.000000,0.000000,0.000000 diag,8,0.000001,0.000000,0.011921,0.000000 qsort,8,0.000001,0.000001,0.011921,0.012500 diag,8,0.000000,0.000000,0.000000,0.000000 sort,16,0.000001,0.000001,0.007451,0.006250 diag,16,0.000001,0.000001,0.005960,0.006250 sort2,16,0.000000,0.000000,0.000000,0.000000 diag,16,0.000001,0.000000,0.007451,0.000000 qsort,16,0.000001,0.000001,0.005960,0.006250 diag,16,0.000001,0.000000,0.005960,0.000000 sort,32,0.000001,0.000000,0.003725,0.000000 diag,32,0.000002,0.000001,0.005960,0.003125 sort2,32,0.000000,0.000001,0.000000,0.003125 diag,32,0.000001,0.000001,0.003725,0.003125 qsort,32,0.000001,0.000001,0.002980,0.003125 diag,32,0.000001,0.000001,0.002980,0.003125 sort,64,0.000002,0.000002,0.002980,0.003125 diag,64,0.000003,0.000003,0.004843,0.004687 sort2,64,0.000001,0.000001,0.001490,0.001562 diag,64,0.000002,0.000002,0.003353,0.003125 qsort,64,0.000003,0.000003,0.004843,0.004687 diag,64,0.000001,0.000001,0.001490,0.001562 sort,128,0.000004,0.000004,0.003166,0.003125 diag,128,0.000012,0.000007,0.009499,0.005469 sort2,128,0.000004,0.000004,0.003166,0.003125 diag,128,0.000004,0.000003,0.003166,0.002344 qsort,128,0.000006,0.000007,0.004657,0.005469 diag,128,0.000003,0.000003,0.002421,0.002344 sort,256,0.000014,0.000013,0.005495,0.005078 diag,256,0.000011,0.000011,0.004284,0.004297 sort2,256,0.000012,0.000012,0.004657,0.004687 diag,256,0.000009,0.000009,0.003539,0.003516 qsort,256,0.000018,0.000018,0.007078,0.007031 diag,256,0.000009,0.000009,0.003539,0.003516 sort,512,0.000050,0.000050,0.009779,0.009766 diag,512,0.000025,0.000024,0.004889,0.004687 sort2,512,0.000043,0.000043,0.008382,0.008398 diag,512,0.000022,0.000022,0.004331,0.004297 qsort,512,0.000031,0.000031,0.006054,0.006055 diag,512,0.000022,0.000022,0.004284,0.004297 sort,1024,0.000197,0.000197,0.019232,0.019238 diag,1024,0.000052,0.000052,0.005076,0.005078 sort2,1024,0.000157,0.000157,0.015320,0.015332 diag,1024,0.000050,0.000049,0.004866,0.004785 qsort,1024,0.000066,0.000066,0.006449,0.006445 diag,1024,0.000049,0.000049,0.004796,0.004785 sort,2048,0.000738,0.000737,0.036042,0.035986 diag,2048,0.000109,0.000109,0.005320,0.005322 sort2,2048,0.000573,0.000572,0.027986,0.027930 diag,2048,0.000128,0.000128,0.006252,0.006250 qsort,2048,0.000146,0.000146,0.007136,0.007129 diag,2048,0.000106,0.000106,0.005169,0.005176 sort,4096,0.002955,0.002954,0.072143,0.072119 diag,4096,0.000234,0.000233,0.005710,0.005688 sort2,4096,0.002273,0.002273,0.055495,0.055493 diag,4096,0.000235,0.000233,0.005739,0.005688 qsort,4096,0.000312,0.000312,0.007619,0.007617 diag,4096,0.000230,0.000230,0.005617,0.005615 sort,8192,0.011985,0.011985,0.146299,0.146301 diag,8192,0.000503,0.000501,0.006141,0.006116 sort2,8192,0.009056,0.009056,0.110545,0.110547 diag,8192,0.000501,0.000502,0.006118,0.006128 qsort,8192,0.000677,0.000675,0.008263,0.008240 diag,8192,0.000500,0.000501,0.006103,0.006116 sort,16384,0.048032,0.048037,0.293164,0.293195 diag,16384,0.001131,0.001130,0.006903,0.006897 sort2,16384,0.036061,0.036067,0.220099,0.220135 diag,16384,0.001150,0.001150,0.007020,0.007019 qsort,16384,0.001447,0.001446,0.008832,0.008826 diag,16384,0.001123,0.001123,0.006854,0.006854 sort,32768,0.190785,0.190680,0.582230,0.581909 diag,32768,0.002548,0.002541,0.007776,0.007755 sort2,32768,0.144712,0.144226,0.441626,0.440143 diag,32768,0.002509,0.002500,0.007656,0.007629 qsort,32768,0.003135,0.003123,0.009567,0.009531 diag,32768,0.002516,0.002504,0.007678,0.007642 sort,65536,0.765225,0.764950,1.167641,1.167221 diag,65536,0.005509,0.005508,0.008406,0.008405 sort2,65536,0.568910,0.568988,0.868088,0.868207 diag,65536,0.005519,0.005518,0.008421,0.008420 qsort,65536,0.006601,0.006599,0.010072,0.010069 diag,65536,0.005501,0.005500,0.008394,0.008392
オケー