#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 < 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_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; aho_type_t* au_j; for (aho_type_t* au_i = au_A + 1; au_i < cu_end_of_data; ++au_i) { // ① aho_type_t u_x = *au_i; // ② 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.000000,0.000000,0.000000,0.000000 diag,1,0.000000,0.000000,0.000000,0.000000 qsort,1,0.000001,0.000001,0.095367,0.100000 diag,1,0.000000,0.000000,0.000000,0.000000 sort,2,0.000000,0.000000,0.000000,0.000000 diag,2,0.000001,0.000000,0.059605,0.000000 sort2,2,0.000001,0.000000,0.047684,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.000000,0.000000,0.000000,0.000000 sort,4,0.000000,0.000001,0.000000,0.025000 diag,4,0.000001,0.000000,0.023842,0.000000 sort2,4,0.000001,0.000000,0.023842,0.000000 diag,4,0.000001,0.000000,0.023842,0.000000 qsort,4,0.000000,0.000000,0.000000,0.000000 diag,4,0.000000,0.000000,0.000000,0.000000 sort,8,0.000000,0.000001,0.000000,0.012500 diag,8,0.000001,0.000000,0.011921,0.000000 sort2,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.000000,0.000000,0.000000 diag,16,0.000000,0.000001,0.000000,0.006250 sort2,16,0.000001,0.000000,0.005960,0.000000 diag,16,0.000000,0.000000,0.000000,0.000000 qsort,16,0.000001,0.000001,0.007451,0.006250 diag,16,0.000000,0.000000,0.000000,0.000000 sort,32,0.000001,0.000000,0.002980,0.000000 diag,32,0.000001,0.000001,0.003725,0.003125 sort2,32,0.000000,0.000001,0.000000,0.003125 diag,32,0.000001,0.000000,0.002980,0.000000 qsort,32,0.000001,0.000002,0.003725,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.000003,0.000002,0.004470,0.003125 sort2,64,0.000001,0.000001,0.001490,0.001562 diag,64,0.000002,0.000001,0.002980,0.001562 qsort,64,0.000003,0.000003,0.004470,0.004687 diag,64,0.000001,0.000001,0.001863,0.001562 sort,128,0.000004,0.000004,0.003166,0.003125 diag,128,0.000005,0.000005,0.003912,0.003906 sort2,128,0.000003,0.000004,0.002421,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.000013,0.000013,0.005122,0.005078 diag,256,0.000017,0.000013,0.006612,0.005078 sort2,256,0.000012,0.000012,0.004657,0.004687 diag,256,0.000009,0.000009,0.003539,0.003516 qsort,256,0.000016,0.000017,0.006240,0.006641 diag,256,0.000008,0.000009,0.003073,0.003516 sort,512,0.000049,0.000048,0.009593,0.009375 diag,512,0.000023,0.000024,0.004470,0.004687 sort2,512,0.000042,0.000041,0.008196,0.008008 diag,512,0.000021,0.000022,0.004098,0.004297 qsort,512,0.000030,0.000029,0.005867,0.005664 diag,512,0.000021,0.000021,0.004098,0.004102 sort,1024,0.000192,0.000192,0.018743,0.018750 diag,1024,0.000050,0.000050,0.004866,0.004883 sort2,1024,0.000153,0.000154,0.014948,0.015039 diag,1024,0.000048,0.000047,0.004703,0.004590 qsort,1024,0.000065,0.000064,0.006333,0.006250 diag,1024,0.000047,0.000046,0.004587,0.004492 sort,2048,0.000719,0.000717,0.035111,0.035010 diag,2048,0.000106,0.000106,0.005180,0.005176 sort2,2048,0.000559,0.000557,0.027299,0.027197 diag,2048,0.000105,0.000104,0.005122,0.005078 qsort,2048,0.000144,0.000145,0.007031,0.007080 diag,2048,0.000104,0.000104,0.005076,0.005078 sort,4096,0.002885,0.002884,0.070437,0.070410 diag,4096,0.000226,0.000226,0.005518,0.005518 sort2,4096,0.002194,0.002195,0.053563,0.053589 diag,4096,0.000224,0.000224,0.005466,0.005469 qsort,4096,0.000307,0.000305,0.007497,0.007446 diag,4096,0.000223,0.000223,0.005448,0.005444 sort,8192,0.011672,0.011672,0.142481,0.142480 diag,8192,0.000484,0.000484,0.005908,0.005908 sort2,8192,0.008946,0.008941,0.109203,0.109143 diag,8192,0.000481,0.000482,0.005873,0.005884 qsort,8192,0.000686,0.000684,0.008373,0.008350 diag,8192,0.000476,0.000477,0.005809,0.005823 sort,16384,0.046939,0.046934,0.286494,0.286462 diag,16384,0.001094,0.001094,0.006678,0.006677 sort2,16384,0.035129,0.035129,0.214411,0.214410 diag,16384,0.001086,0.001086,0.006628,0.006628 qsort,16384,0.001402,0.001401,0.008558,0.008551 diag,16384,0.001084,0.001084,0.006617,0.006616 sort,32768,0.187773,0.187768,0.573038,0.573022