Changeset 3fb7f5e
- Timestamp:
- Apr 14, 2017, 4:51:13 PM (8 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
- Children:
- 1504536, e3de500
- Parents:
- 3895b8b5
- Location:
- doc/generic_types
- Files:
-
- 18 edited
Legend:
- Unmodified
- Added
- Removed
-
TabularUnified doc/generic_types/evaluation/Makefile ¶
r3895b8b5 r3fb7f5e 33 33 CFAOBJS = cfa-stack.o cfa-pair.o cfa-print.o 34 34 35 CFILES = c-bench.c bench.h $(COBJS:.o=.h) $(COBJS:.o=.c) 36 CPPFILES = cpp-bench.cpp bench.hpp cpp-stack.hpp cpp-print.hpp 37 CPPVFILES = cpp-vbench.cpp bench.hpp object.hpp $(CPPVOBJS:.o=.hpp) $(CPPVOBJS:.o=.cpp) cpp-vprint.hpp 38 CFAFILES = cfa-bench.c bench.h cfa-stack.h cfa-print.h cfa-stack.c cfa-print.c 39 35 40 c-bench: c-bench.c c-bench.d $(COBJS) 36 41 $(COMPILE.c) -o $@ $< $(COBJS) $(LDFLAGS) … … 61 66 @echo '## C ##' 62 67 @/usr/bin/time -f 'max_memory:\t%M kilobytes' ./c-bench 63 @printf 'source_size:\t%8d lines\n' `cat c-bench.c bench.h c-stack.{h,c} c-pair.{h,c} c-print.{h,c} | wc -l` 68 @printf 'source_size:\t%8d lines\n' `cat $(CFILES) | wc -l` 69 @printf 'redundant_type_annotations:%8d count\n' `cat $(CFILES) | fgrep '/***/' -c` 64 70 @printf 'binary_size:\t%8d bytes\n' `stat -c %s c-bench` 65 71 … … 68 74 @echo '## Cforall ##' 69 75 @/usr/bin/time -f 'max_memory:\t %M kilobytes' ./cfa-bench 70 @printf 'source_size:\t%8d lines\n' `cat cfa-bench.c bench.h cfa-stack.h cfa-stack.c cfa-print.h cfa-print.c | wc -l` 76 @printf 'source_size:\t%8d lines\n' `cat $(CFAFILES) | wc -l` 77 @printf 'redundant_type_annotations:%8d count\n' `cat $(CFAFILES) | fgrep '/***/' -c` 71 78 @printf 'binary_size:\t%8d bytes\n' `stat -c %s cfa-bench` 72 79 … … 75 82 @echo '## C++ ##' 76 83 @/usr/bin/time -f 'max_memory:\t %M kilobytes' ./cpp-bench 77 @printf 'source_size:\t%8d lines\n' `cat cpp-bench.cpp bench.hpp cpp-stack.hpp cpp-print.hpp | wc -l` 84 @printf 'source_size:\t%8d lines\n' `cat $(CPPFILES) | wc -l` 85 @printf 'redundant_type_annotations:%8d count\n' `cat $(CPPFILES) | fgrep '/***/' -c` 78 86 @printf 'binary_size:\t%8d bytes\n' `stat -c %s cpp-bench` 79 87 … … 82 90 @echo '## C++ virtual ##' 83 91 @/usr/bin/time -f 'max_memory:\t%M kilobytes' ./cpp-vbench 84 @printf 'source_size:\t%8d lines\n' `cat cpp-vbench.cpp bench.hpp object.hpp cpp-vstack.{hpp,cpp} cpp-vprint.hpp | wc -l` 92 @printf 'source_size:\t%8d lines\n' `cat $(CPPVFILES) | wc -l` 93 @printf 'redundant_type_annotations:%8d count\n' `cat $(CPPVFILES) | fgrep '/***/' -c` 85 94 @printf 'binary_size:\t%8d bytes\n' `stat -c %s cpp-vbench` 86 95 -
TabularUnified doc/generic_types/evaluation/bench.h ¶
r3895b8b5 r3fb7f5e 20 20 } 21 21 22 #define REPEAT_TIMED(name, code) TIMED( name, for (int _i = 0; _i < N; ++_i) { code } ) 22 #define REPEAT_N_TIMED(name, n, code) TIMED( name, for (int _i = 0; _i < n; ++_i) { code } ) 23 24 #define REPEAT_TIMED(name, code) REPEAT_N_TIMED(name, N, code) -
TabularUnified doc/generic_types/evaluation/bench.hpp ¶
r3895b8b5 r3fb7f5e 21 21 } 22 22 23 #define REPEAT_TIMED(name, code) TIMED( name, for (int _i = 0; _i < N; ++_i) { code } ) 23 #define REPEAT_N_TIMED(name, n, code) TIMED( name, for (int _i = 0; _i < n; ++_i) { code } ) 24 25 #define REPEAT_TIMED(name, code) REPEAT_N_TIMED(name, N, code) -
TabularUnified doc/generic_types/evaluation/c-bench.c ¶
r3895b8b5 r3fb7f5e 7 7 8 8 _Bool* new_bool( _Bool b ) { 9 _Bool* q = malloc(sizeof(_Bool)); 9 _Bool* q = malloc(sizeof(_Bool)); /***/ 10 10 *q = b; 11 11 return q; … … 13 13 14 14 char* new_char( char c ) { 15 char* q = malloc(sizeof(char)); 15 char* q = malloc(sizeof(char)); /***/ 16 16 *q = c; 17 17 return q; … … 19 19 20 20 int* new_int( int i ) { 21 int* q = malloc(sizeof(int)); 21 int* q = malloc(sizeof(int)); /***/ 22 22 *q = i; 23 23 return q; 24 24 } 25 25 26 void* copy_bool( const void* p ) { return new_bool( *(const _Bool*)p ); } 26 void* copy_bool( const void* p ) { return new_bool( *(const _Bool*)p ); } /***/ 27 27 28 void* copy_char( const void* p ) { return new_char( *(const char*)p ); } 28 void* copy_char( const void* p ) { return new_char( *(const char*)p ); } /***/ 29 29 30 void* copy_int( const void* p ) { return new_int( *(const int*)p ); } 30 void* copy_int( const void* p ) { return new_int( *(const int*)p ); } /***/ 31 31 32 void* copy_pair_bool_char( const void* p ) { return copy_pair( p, copy_bool, copy_char ); } 32 void* copy_pair_bool_char( const void* p ) { return copy_pair( p, copy_bool, copy_char ); } /***/ 33 33 34 void free_pair_bool_char( void* p ) { free_pair( p, free, free ); } 34 void free_pair_bool_char( void* p ) { free_pair( p, free, free ); } /***/ 35 35 36 36 int cmp_bool( const void* a, const void* b ) { 37 return *(const _Bool*)a == *(const _Bool*)b ? 0 : *(const _Bool*)a < *(const _Bool*)b ? -1 : 1; 37 return *(const _Bool*)a == *(const _Bool*)b ? 0 : *(const _Bool*)a < *(const _Bool*)b ? -1 : 1; /***/ 38 38 } 39 39 40 40 int cmp_char( const void* a, const void* b ) { 41 return *(const char*)a == *(const char*)b ? 0 : *(const char*)a < *(const char*)b ? -1 : 1; 41 return *(const char*)a == *(const char*)b ? 0 : *(const char*)a < *(const char*)b ? -1 : 1; /***/ 42 42 } 43 43 44 44 int main(int argc, char** argv) { 45 FILE* out = fopen("c-out.txt", "w"); 45 46 srand(20171025); 46 47 … … 52 53 struct stack t; 53 54 TIMED( "copy_int", 54 copy_stack(&t, &s, copy_int); 55 copy_stack(&t, &s, copy_int); /***/ 55 56 ) 56 57 57 58 TIMED( "clear_int", 58 clear_stack(&s, free); 59 clear_stack(&s, free); /***/ 59 60 ) 60 61 61 62 int max = 0; 62 63 REPEAT_TIMED( "pop_int", 63 int* x = pop_stack(&t); 64 int* x = pop_stack(&t); /***/ 64 65 if ( *x > max ) { max = *x; } 65 66 free(x); 67 ) 68 print( out, "d", max, "\n" ); /***/ 69 70 REPEAT_N_TIMED( "print_int", N/2, 71 print( out, "dsds", rand(), ":", rand(), "\n" ); /***/ 66 72 ) 67 73 … … 73 79 struct stack t2; 74 80 TIMED( "copy_bool_char", 75 copy_stack(&t2, &s2, copy_pair_bool_char); 81 copy_stack(&t2, &s2, copy_pair_bool_char); /***/ 76 82 ) 77 83 78 84 TIMED( "clear_bool_char", 79 clear_stack(&s2, free_pair_bool_char); 85 clear_stack(&s2, free_pair_bool_char); /***/ 80 86 ) 81 87 82 88 struct pair* max2 = new_pair( new_bool(0), new_char('\0') ); 83 89 REPEAT_TIMED( "pop_bool_char", 84 struct pair* x = pop_stack(&t2); 85 if ( cmp_pair( x, max2, cmp_bool, cmp_char ) > 0 ) { 86 free_pair_bool_char( max2 ); 90 struct pair* x = pop_stack(&t2); /***/ 91 if ( cmp_pair( x, max2, cmp_bool, cmp_char ) > 0 ) { /***/ 92 free_pair_bool_char( max2 ); /***/ 87 93 max2 = x; 88 94 } else { 89 free_pair_bool_char( x ); 95 free_pair_bool_char( x ); /***/ 90 96 } 91 97 ) 92 free_pair_bool_char( max2 ); 98 print( out, "pbc", *max2, "\n" ); /***/ 99 free_pair_bool_char( max2 ); /***/ 93 100 94 FILE* out = fopen("c-out.txt", "w"); 95 REPEAT_TIMED( "print_int", 96 print( out, "dsds", rand(), ":", rand(), "\n" ); 101 REPEAT_N_TIMED( "print_pair", N/2, 102 struct pair p1 = ((struct pair){ new_bool(rand() & 0x1), new_char(rand() & 0x7F) }); /***/ 103 struct pair p2 = ((struct pair){ new_bool(rand() & 0x1), new_char(rand() & 0x7F) }); /***/ 104 print( out, "pbcspbcs", p1, ":", p2, "\n" ); /***/ 105 free(p1.first); free(p1.second); /***/ 106 free(p2.first); free(p2.second); /***/ 97 107 ) 98 99 REPEAT_TIMED( "print_pair", 100 struct pair p1 = ((struct pair){ new_bool(rand() & 0x1), new_char(rand() & 0x7F) }); 101 struct pair p2 = ((struct pair){ new_bool(rand() & 0x1), new_char(rand() & 0x7F) }); 102 print( out, "pbcspbcs", p1, ":", p2, "\n" ); 103 free(p1.first); free(p1.second); 104 free(p2.first); free(p2.second); 105 ) 108 106 109 fclose(out); 107 110 } -
TabularUnified doc/generic_types/evaluation/c-pair.c ¶
r3895b8b5 r3fb7f5e 3 3 4 4 struct pair* new_pair(void* first, void* second) { 5 struct pair* p = malloc(sizeof(struct pair)); 6 *p = (struct pair){ first, second }; 5 struct pair* p = malloc(sizeof(struct pair)); /***/ 6 *p = (struct pair){ first, second }; /***/ 7 7 return p; 8 8 } -
TabularUnified doc/generic_types/evaluation/c-print.c ¶
r3895b8b5 r3fb7f5e 17 17 void print_fmt(FILE* out, char fmt, void* p) { 18 18 switch( fmt ) { 19 case 's': print_string(out, (const char*)p); break; 20 case 'b': print_bool(out, *(_Bool*)p); break; 21 case 'c': print_char(out, *(char*)p); break; 22 case 'd': print_int(out, *(int*)p); break; 19 case 's': print_string(out, (const char*)p); break; /***/ 20 case 'b': print_bool(out, *(_Bool*)p); break; /***/ 21 case 'c': print_char(out, *(char*)p); break; /***/ 22 case 'd': print_int(out, *(int*)p); break; /***/ 23 23 } 24 24 } … … 29 29 for (const char* it = fmt; *it; ++it) { 30 30 switch( *it ) { 31 case 's': print_string(out, va_arg(args, const char*)); break; 32 case 'b': print_bool(out, va_arg(args, int)); break; 33 case 'c': print_char(out, va_arg(args, int)); break; 34 case 'd': print_int(out, va_arg(args, int)); break; 31 case 's': print_string(out, va_arg(args, const char*)); break; /***/ 32 case 'b': print_bool(out, va_arg(args, int)); break; /***/ 33 case 'c': print_char(out, va_arg(args, int)); break; /***/ 34 case 'd': print_int(out, va_arg(args, int)); break; /***/ 35 35 case 'p': { 36 const struct pair x = va_arg(args, const struct pair); 36 const struct pair x = va_arg(args, const struct pair); /***/ 37 37 fprintf(out, "["); 38 print_fmt(out, *++it, x.first); 38 print_fmt(out, *++it, x.first); /***/ 39 39 fprintf(out, ", "); 40 print_fmt(out, *++it, x.second); 40 print_fmt(out, *++it, x.second); /***/ 41 41 fprintf(out, "]"); 42 42 break; -
TabularUnified doc/generic_types/evaluation/c-stack.c ¶
r3895b8b5 r3fb7f5e 8 8 9 9 struct stack new_stack() { 10 return (struct stack){ NULL }; 10 return (struct stack){ NULL }; /***/ 11 11 } 12 12 … … 15 15 struct stack_node* next = t->head; 16 16 while ( next ) { 17 *crnt = malloc(sizeof(struct stack_node)); 18 **crnt = (struct stack_node){ copy(next->value) }; 17 *crnt = malloc(sizeof(struct stack_node)); /***/ 18 **crnt = (struct stack_node){ copy(next->value) }; /***/ 19 19 crnt = &(*crnt)->next; 20 20 next = next->next; … … 39 39 40 40 void push_stack(struct stack* s, void* value) { 41 struct stack_node* n = malloc(sizeof(struct stack_node)); 42 *n = (struct stack_node){ value, s->head }; 41 struct stack_node* n = malloc(sizeof(struct stack_node)); /***/ 42 *n = (struct stack_node){ value, s->head }; /***/ 43 43 s->head = n; 44 44 } -
TabularUnified doc/generic_types/evaluation/cfa-bench.c ¶
r3895b8b5 r3fb7f5e 8 8 9 9 int main(int argc, char** argv) { 10 FILE* out = fopen("cfa-out.txt", "w"); 10 11 srand(20171025); 11 12 … … 28 29 max = max( max, pop( &t ) ); 29 30 ) 31 print( out, max, "\n" ); 32 33 REPEAT_N_TIMED( "print_int", N/2, 34 print( out, rand(), ":", rand(), "\n" ); 35 ) 30 36 31 37 stack(pair(_Bool, char)) s2; … … 47 53 max2 = max( max2, pop( &t2 ) ); 48 54 ) 55 print( out, max2, "\n" ); 49 56 50 FILE* out = fopen("cfa-out.txt", "w"); 51 REPEAT_TIMED( "print_int", 52 print( out, rand(), ":", rand(), "\n" ); 53 ) 54 55 REPEAT_TIMED( "print_pair", 57 REPEAT_N_TIMED( "print_pair", N/2, 56 58 print( out, (pair(_Bool, char)){ rand() & 0x1, rand() & 0x7F }, ":", 57 59 (pair(_Bool, char)){ rand() & 0x1, rand() & 0x7F }, "\n" ); -
TabularUnified doc/generic_types/evaluation/cfa-stack.c ¶
r3895b8b5 r3fb7f5e 15 15 stack_node(T)* next = t->head; 16 16 while ( next ) { 17 *crnt = ((stack_node(T)*)malloc()){ next->value }; 17 *crnt = ((stack_node(T)*)malloc()){ next->value }; /***/ 18 18 stack_node(T)* acrnt = *crnt; 19 19 crnt = &acrnt->next; … … 27 27 stack_node(T)* next = t.head; 28 28 while ( next ) { 29 *crnt = ((stack_node(T)*)malloc()){ next->value }; 29 *crnt = ((stack_node(T)*)malloc()){ next->value }; /***/ 30 30 stack_node(T)* acrnt = *crnt; 31 31 crnt = &acrnt->next; … … 51 51 52 52 forall(otype T) void push(stack(T)* s, T value) { 53 s->head = ((stack_node(T)*)malloc()){ value, s->head }; 53 s->head = ((stack_node(T)*)malloc()){ value, s->head }; /***/ 54 54 } 55 55 -
TabularUnified doc/generic_types/evaluation/cpp-bench.cpp ¶
r3895b8b5 r3fb7f5e 8 8 9 9 int main(int argc, char** argv) { 10 std::ofstream out{"cpp-out.txt"}; 10 11 srand(20171025); 11 12 … … 28 29 max = std::max( max, t.pop() ); 29 30 ) 31 print( out, max, "\n" ); 32 33 REPEAT_N_TIMED( "print_int", N/2, 34 print( out, rand(), ":", rand(), "\n" ); 35 ) 30 36 31 37 stack<std::pair<bool, char>> s2; … … 47 53 max2 = std::max( max2, t2.pop() ); 48 54 ) 55 print( out, max2, "\n" ); 49 56 50 std::ofstream out{"cpp-out.txt"}; 51 REPEAT_TIMED( "print_int", 52 print( out, rand(), ":", rand(), "\n" ); 53 ) 54 55 REPEAT_TIMED( "print_pair", 57 REPEAT_N_TIMED( "print_pair", N/2, 56 58 print( out, std::pair<bool, char>{ rand() & 0x1, rand() & 0x7F }, ":", 57 59 std::pair<bool, char>{ rand() & 0x1, rand() & 0x7F }, "\n" ); -
TabularUnified doc/generic_types/evaluation/cpp-stack.hpp ¶
r3895b8b5 r3fb7f5e 18 18 node* next = o.head; 19 19 while ( next ) { 20 *crnt = new node{ next->value }; 20 *crnt = new node{ next->value }; /***/ 21 21 crnt = &(*crnt)->next; 22 22 next = next->next; … … 63 63 64 64 void push(T&& value) { 65 head = new node{ std::move(value), head }; 65 head = new node{ std::move(value), head }; /***/ 66 66 } 67 67 -
TabularUnified doc/generic_types/evaluation/cpp-vbench.cpp ¶
r3895b8b5 r3fb7f5e 8 8 9 9 int main(int argc, char** argv) { 10 std::ofstream out{"cpp-vout.txt"}; 10 11 srand(20171025); 11 12 … … 26 27 integer max; 27 28 REPEAT_TIMED( "pop_int", 28 max = std::max( max, t.pop()->as<integer>() ); 29 max = std::max( max, t.pop()->as<integer>() ); /***/ 30 ) 31 print( out, max, c_string{"\n"} ); 32 33 REPEAT_N_TIMED( "print_int", N/2, 34 print( out, integer{rand()}, c_string{":"}, integer{rand()}, c_string{"\n"} ); 29 35 ) 30 36 … … 47 53 std::make_unique<character>('\0') ); 48 54 REPEAT_TIMED( "pop_bool_char", 49 std::unique_ptr<pair> x = as_ptr<pair>( t2.pop() ); 55 std::unique_ptr<pair> x = as_ptr<pair>( t2.pop() ); /***/ 50 56 if ( *x > *max2 ) { max2 = std::move(x); } 51 57 ) 58 print( out, *max2, c_string{"\n"} ); 52 59 53 std::ofstream out{"cpp-vout.txt"}; 54 REPEAT_TIMED( "print_int", 55 print( out, integer{rand()}, c_string{":"}, integer{rand()}, c_string{"\n"} ); 56 ) 57 58 REPEAT_TIMED( "print_pair", 60 REPEAT_N_TIMED( "print_pair", N/2, 59 61 print( out, pair{ std::make_unique<boolean>( rand() & 0x1 ), 60 62 std::make_unique<character>( rand() & 0x7F ) }, c_string{":"}, -
TabularUnified doc/generic_types/evaluation/cpp-vstack.cpp ¶
r3895b8b5 r3fb7f5e 55 55 56 56 void stack::push(std::unique_ptr<object>&& value) { 57 head = new node{ std::move(value), head }; 57 head = new node{ std::move(value), head }; /***/ 58 58 } 59 59 -
TabularUnified doc/generic_types/evaluation/object.hpp ¶
r3895b8b5 r3fb7f5e 96 96 } 97 97 98 object& operator= (const object& that) override { return *this = that.as<boolean>(); } 98 object& operator= (const object& that) override { return *this = that.as<boolean>(); } /***/ 99 99 100 100 ~boolean() override = default; … … 102 102 int cmp(const boolean& that) const { return x == that.x ? 0 : x == false ? -1 : 1; } 103 103 104 int cmp(const ordered& that) const override { return cmp( that.as<boolean>() ); } 104 int cmp(const ordered& that) const override { return cmp( that.as<boolean>() ); } /***/ 105 105 106 106 void print(std::ostream& out) const override { out << (x ? "true" : "false"); } … … 124 124 } 125 125 126 object& operator= (const object& that) override { return *this = that.as<character>(); } 126 object& operator= (const object& that) override { return *this = that.as<character>(); } /***/ 127 127 128 128 ~character() override = default; … … 130 130 int cmp(const character& that) const { return x == that.x ? 0 : x < that.x ? -1 : 1; } 131 131 132 int cmp(const ordered& that) const override { return cmp( that.as<character>() ); } 132 int cmp(const ordered& that) const override { return cmp( that.as<character>() ); } /***/ 133 133 134 134 void print(std::ostream& out) const override { … … 155 155 } 156 156 157 object& operator= (const object& that) override { return *this = that.as<integer>(); } 157 object& operator= (const object& that) override { return *this = that.as<integer>(); } /***/ 158 158 159 159 ~integer() override = default; … … 161 161 int cmp(const integer& that) const { return x == that.x ? 0 : x < that.x ? -1 : 1; } 162 162 163 int cmp(const ordered& that) const override { return cmp( that.as<integer>() ); } 163 int cmp(const ordered& that) const override { return cmp( that.as<integer>() ); } /***/ 164 164 165 165 void print(std::ostream& out) const override { out << x; } … … 183 183 } 184 184 185 object& operator= (const object& that) override { return *this = that.as<c_string>(); } 185 object& operator= (const object& that) override { return *this = that.as<c_string>(); } /***/ 186 186 187 187 ~c_string() override = default; … … 212 212 } 213 213 214 object& operator= (const object& that) override { return *this = that.as<pair>(); } 214 object& operator= (const object& that) override { return *this = that.as<pair>(); } /***/ 215 215 216 216 ~pair() override = default; 217 217 218 218 int cmp(const pair& that) const { 219 int c = x->as<ordered>().cmp( that.x->as<ordered>() ); 219 int c = x->as<ordered>().cmp( that.x->as<ordered>() ); /***/ 220 220 if ( c != 0 ) return c; 221 return y->as<ordered>().cmp( that.y->as<ordered>() ); 221 return y->as<ordered>().cmp( that.y->as<ordered>() ); /***/ 222 222 } 223 223 … … 226 226 void print(std::ostream& out) const override { 227 227 out << "["; 228 x->as<printable>().print(out); 228 x->as<printable>().print(out); /***/ 229 229 out << ", "; 230 y->as<printable>().print(out); 230 y->as<printable>().print(out); /***/ 231 231 out << "]"; 232 232 } -
TabularUnified doc/generic_types/evaluation/timing.csv ¶
r3895b8b5 r3fb7f5e 1 "400 million repetitions","C","\\CFA{}","\\CC{}","\\CC{obj}","units" 2 "push\nint",3379,2616,1928,3527,"ms" 3 "copy\nint",3036,2268,1564,3182,"ms" 4 "clear\nint",1389,834,751,1502,"ms" 5 "pop\nint",1421,2728,738,5245,"ms" 6 "push\npair",4598,3708,1776,7302,"ms" 7 "copy\npair",6367,1920,1009,6982,"ms" 8 "clear\npair",2906,875,732,3387,"ms" 9 "pop\npair",3136,8283,861,21669,"ms" 10 "print\nint",17373,17157,9779,10051,"ms" 11 "print\npair",24862,27693,20599,42533,"ms" 1 "400 million repetitions","C","\\CFA{}","\\CC{}","\\CC{obj}" 2 "push\nint",3358,2616,1929,3559 3 "copy\nint",2966,2268,1534,3097 4 "clear\nint",1343,834,708,1487 5 "pop\nint",1385,2728,711,5122 6 "print\nint",6609,17157,5006,5023 7 "push\npair",4930,3708,1795,7136 8 "copy\npair",6203,1920,996,7043 9 "clear\npair",2811,875,712,3393 10 "pop\npair",3054,8283,883,21262 11 "print\npair",12364,27693,10448,21468 12 -
TabularUnified doc/generic_types/evaluation/timing.gp ¶
r3895b8b5 r3fb7f5e 12 12 set boxwidth 0.8 13 13 14 set ylabel " seconds"14 set ylabel "milliseconds" 15 15 set key top left reverse Left 16 16 -
TabularUnified doc/generic_types/generic_types.tex ¶
r3895b8b5 r3fb7f5e 958 958 The \CCV variant illustrates an alternative object-oriented idiom where all objects inherit from a base @object@ class, mimicking a Java-like interface; 959 959 hence runtime checks are necessary to safely down-cast objects. 960 The most notable difference among the implementations is in optimizations: \CFA and \CC inline the stack and pair elements into corresponding list and pair nodes, while the C and \CCV lack generic-type capability {\color{red}(AWKWARD) to store generic objects via pointers to separately-allocated objects}.961 For the print benchmark, idiomatic printing is used: the C and \CFA variants use d @cstdio.h@, while the \CC and \CCV variants used@iostream@.962 Preliminary tests show th edifference has little runtime effect.960 The most notable difference among the implementations is in memory layout of generic types: \CFA and \CC inline the stack and pair elements into corresponding list and pair nodes, while C and \CCV lack such a capability and store generic objects via pointers to separately-allocated objects instead. 961 For the print benchmark, idiomatic printing is used: the C and \CFA variants use @stdio.h@, while the \CC and \CCV variants use @iostream@. 962 Preliminary tests show this difference has little runtime effect. 963 963 Finally, the C @rand@ function is used generate random numbers. 964 964 … … 975 975 \newcommand{\CT}[1]{\multicolumn{1}{c}{#1}} 976 976 \begin{tabular}{r|rrrr} 977 & \CT{C} & \CT{\CFA} & \CT{\CC} & \CT{\CCV} \\ \hline 978 maximum memory usage (MB) & 10001 & 2501 & 2503 & 11253 \\ 979 source code size (lines) & 301 & 224 & 188 & 437 \\ 980 binary size (KB) & 18 & 234 & 18 & 42 \\ 977 & \CT{C} & \CT{\CFA} & \CT{\CC} & \CT{\CCV} \\ \hline 978 maximum memory usage (MB) & 10001 & 2501 & 2503 & 11253 \\ 979 source code size (lines) & 301 & 224 & 188 & 437 \\ 980 redundant type annotations (lines) & 46 & 3 & 2 & 15 \\ 981 binary size (KB) & 18 & 234 & 18 & 42 \\ 981 982 \end{tabular} 982 983 \end{table} 983 984 984 985 Figure~\ref{fig:eval} and Table~\ref{tab:eval} show the benchmark results. 985 Each data point is the time for 40M function call, repeated times whereappropriate.986 The five functions are $N$ stack pushes of randomly generated elements, deep copy of an $N$ element stack, clearing all nodes of an $N$ element stack, $N /2$ variadic @print@ calls each containing two constant strings and two stack elements \TODO{right now $N$ fresh elements: FIX}, and $N$ stack pops, keeping a running record of the maximum element to ensure that the object copies are not optimized out.986 Each data point is the time for $N = 40M$ function calls or loop iterations, as appropriate. 987 The five functions are $N$ stack pushes of randomly generated elements, deep copy of an $N$ element stack, clearing all nodes of an $N$ element stack, $N$ stack pops (keeping a running record of the maximum element to ensure that the object copies are not optimized out), and $N/2$ variadic @print@ calls each containing two constant strings and two stack elements. 987 988 These five functions are run first for a stack of integers, and second for a stack of generic pairs of a boolean and a @char@. 988 989 \TODO{} The data shown is the median of 5 consecutive runs of each program, with an initial warm-up run omitted. … … 993 994 994 995 \CC performs best because it uses header-only inlined libraries (i.e., no separate compilation). 995 \CFA and \CC have the advantage of a pre-written generic @pair@ type to reduce line count, while C and \CCV require it to written by the programmer. {\color{red} Why?} 996 The definition of @object@ and wrapper classes for @bool@, @char@, @int@, and @const char *@ are included in the line count for \CCV, which somewhat inflates its line count, as an actual object-oriented language would include these in the standard library and with their omission the \CCV line count is similar to C; 997 we justify the given line count by the fact that many object-oriented languages do not allow implementing new interfaces on library types without subclassing or boilerplate-filled wrapper types, which may be similarly verbose. 996 \CFA and \CC have the advantage of a pre-written generic @pair@ type to reduce line count, while C and \CCV require it to written by the programmer, as C does not have a generic collections library in its standard distribution and \CCV does not use the \CC standard template library by construction. 997 The definition of @object@ and wrapper classes for @bool@, @char@, @int@, and @const char *@ are included in the line count for \CCV, which somewhat inflates its line count, as an actual object-oriented language would include these in the standard library; with their omission the \CCV line count is similar to C. 998 We justify the given line count by noting that many object-oriented languages do not allow implementing new interfaces on library types without subclassing or boilerplate-filled wrapper types, which may be similarly verbose. 999 998 1000 Raw line-count, however, is a fairly rough measure of code complexity; 999 1001 another important factor is how much type information the programmer must manually specify, especially where that information is not checked by the compiler. 1000 Such un-checked type information produces a heavier documentation burden and increased potential for runtime bugs, and is much less common in \CFA than C, with its manually specified function pointers arguments and format codes, or \CCV, with its extensive use of un-type-checked downcasts (\eg @object@ to @integer@ when popping a stack, or @object@ to @printable@ when printing the elements of a @pair@) \TODO{Actually calculate this; I want to put a distinctive comment in the source code and grep for it}. 1001 1002 Such un-checked type information produces a heavier documentation burden and increased potential for runtime bugs, and is much less common in \CFA than C, with its manually specified function pointers arguments and format codes, or \CCV, with its extensive use of un-type-checked downcasts (\eg @object@ to @integer@ when popping a stack, or @object@ to @printable@ when printing the elements of a @pair@). To quantify this, the ``redundant type annotations'' line in Table~\ref{tab:eval} counts the number of lines on which the type of a known variable is re-specified, either as a format specifier, explicit downcast, type-specific function, or by name in a @sizeof@, struct literal, or @new@ expression. The \CC benchmark uses two redundant type annotations to create a new stack nodes, while the C and \CCV benchmarks have several such annotations spread throughout their code. The three instances in which the \CFA benchmark still uses redundant type specifiers are to cast the result of a polymorphic @malloc@ call (the @sizeof@ argument is inferred by the compiler). These uses are similar to the @new@ expressions in \CC, though ongoing work on the \CFA compiler's type resolver should shortly render even these type casts superfluous. 1002 1003 1003 1004 \section{Related Work} … … 1088 1089 \appendix 1089 1090 1090 1091 1091 \section{BenchMarks} 1092 1092 \label{sec:BenchMarks}
Note: See TracChangeset
for help on using the changeset viewer.