#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; 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_qsort; double rs; double re; clock_t us; clock_t ue; argc= argc;argv= argv; for (size_t i = 0; i < 18; ++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_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(); 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++; } }
Standard input is empty
sort,1,0.000002,0.000001,0.190735,0.100000 diag,1,0.000002,0.000001,0.190735,0.100000 qsort,1,0.000001,0.000001,0.095367,0.100000 diag,1,0.000000,0.000001,0.000000,0.100000 sort,2,0.000001,0.000000,0.047684,0.000000 diag,2,0.000000,0.000001,0.000000,0.050000 qsort,2,0.000001,0.000000,0.047684,0.000000 diag,2,0.000001,0.000000,0.047684,0.000000 sort,4,0.000000,0.000000,0.000000,0.000000 diag,4,0.000000,0.000001,0.000000,0.025000 qsort,4,0.000000,0.000000,0.000000,0.000000 diag,4,0.000000,0.000000,0.000000,0.000000 sort,8,0.000001,0.000000,0.011921,0.000000 diag,8,0.000001,0.000000,0.014901,0.000000 qsort,8,0.000000,0.000001,0.000000,0.012500 diag,8,0.000001,0.000000,0.011921,0.000000 sort,16,0.000000,0.000001,0.000000,0.006250 diag,16,0.000001,0.000000,0.007451,0.000000 qsort,16,0.000000,0.000001,0.000000,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 qsort,32,0.000001,0.000002,0.002980,0.006250 diag,32,0.000001,0.000000,0.002980,0.000000 sort,64,0.000002,0.000001,0.003353,0.001562 diag,64,0.000002,0.000003,0.002980,0.004687 qsort,64,0.000003,0.000003,0.004843,0.004687 diag,64,0.000002,0.000002,0.003353,0.003125 sort,128,0.000003,0.000004,0.002421,0.003125 diag,128,0.000006,0.000005,0.004657,0.003906 qsort,128,0.000007,0.000006,0.005402,0.004687 diag,128,0.000004,0.000003,0.003166,0.002344 sort,256,0.000013,0.000013,0.005122,0.005078 diag,256,0.000011,0.000011,0.004284,0.004297 qsort,256,0.000022,0.000017,0.008661,0.006641 diag,256,0.000010,0.000010,0.003912,0.003906 sort,512,0.000049,0.000049,0.009593,0.009570 diag,512,0.000023,0.000023,0.004517,0.004492 qsort,512,0.000031,0.000030,0.006054,0.005859 diag,512,0.000022,0.000023,0.004284,0.004492 sort,1024,0.000191,0.000192,0.018650,0.018750 diag,1024,0.000050,0.000051,0.004866,0.004980 qsort,1024,0.000064,0.000064,0.006240,0.006250 diag,1024,0.000049,0.000049,0.004796,0.004785 sort,2048,0.000718,0.000717,0.035053,0.035010 diag,2048,0.000107,0.000106,0.005227,0.005176 qsort,2048,0.000140,0.000140,0.006834,0.006836 diag,2048,0.000104,0.000104,0.005076,0.005078 sort,4096,0.002903,0.002903,0.070879,0.070874 diag,4096,0.000225,0.000226,0.005495,0.005518 qsort,4096,0.000303,0.000304,0.007398,0.007422 diag,4096,0.000227,0.000225,0.005541,0.005493 sort,8192,0.011710,0.011706,0.142943,0.142896 diag,8192,0.000490,0.000490,0.005981,0.005981 qsort,8192,0.000667,0.000665,0.008140,0.008118 diag,8192,0.000486,0.000486,0.005931,0.005933 sort,16384,0.048225,0.048218,0.294343,0.294299 diag,16384,0.001100,0.001099,0.006714,0.006708 qsort,16384,0.001408,0.001406,0.008594,0.008582 diag,16384,0.001141,0.001141,0.006965,0.006964 sort,32768,0.193648,0.193558,0.590966,0.590692 diag,32768,0.002456,0.002455,0.007495,0.007492 qsort,32768,0.003000,0.002998,0.009155,0.009149 diag,32768,0.002443,0.002442,0.007456,0.007452 sort,65536,0.751056,0.750842,1.146020,1.145694 diag,65536,0.005530,0.005529,0.008438,0.008437 qsort,65536,0.006428,0.006426,0.009808,0.009805 diag,65536,0.005572,0.005568,0.008502,0.008496 sort,131072,2.991084,2.989660,2.282016,2.280930 diag,131072,0.013571,0.013565,0.010354,0.010349 qsort,131072,0.013564,0.013561,0.010349,0.010346 diag,131072,0.013754,0.013751,0.010494,0.010491
オケー