source: doc/theses/aaron_moss_PhD/phd/generic-bench.tex@ b28ce93

Last change on this file since b28ce93 was f845e80, checked in by Aaron Moss <a3moss@…>, 6 years ago

thesis: apply round 2 revisions and strip change bars

  • Property mode set to 100644
File size: 4.6 KB
Line 
1\chapter{Generic Stack Benchmarks} \label{generic-bench-app}
2
3This appendix includes the generic stack code for all four language variants discussed in Section~\ref{generic-performance-sec}. Throughout, !/***/! designates a counted redundant type annotation; these include !sizeof! on a known type, repetition of a type name in initialization or return statements, and type-specific helper functions.
4The code is reformatted slightly for brevity.
5
6\section{C}
7
8\begin{cfa}
9typedef struct node {
10 void * value;
11 struct node * next;
12} node;
13typedef struct stack {
14 struct node * head;
15} stack;
16void copy_stack( stack * s, const stack * t, void * (*copy)( const void * ) ) {
17 node ** cr = &s->head;
18 for (node * nx = t->head; nx; nx = nx->next) {
19 *cr = malloc( sizeof(node) ); /***/
20 (*cr)->value = copy( nx->value );
21 cr = &(*cr)->next;
22 }
23 *cr = NULL;
24}
25void clear_stack( stack * s, void (* free_el)( void * ) ) {
26 for ( node * nx = s->head; nx; ) {
27 node * cr = nx;
28 nx = cr->next;
29 free_el( cr->value );
30 free( cr );
31 }
32 s->head = NULL;
33}
34stack new_stack() {
35 return (stack){ NULL }; /***/
36}
37stack * assign_stack( stack * s, const stack * t, void * (*copy_el)( const void * ),
38 void (*free_el)( void * ) ) {
39 if ( s->head == t->head ) return s;
40 clear_stack( s, free_el ); /***/
41 copy_stack( s, t, copy_el ); /***/
42 return s;
43}
44_Bool stack_empty( const stack * s ) {
45 return s->head == NULL;
46}
47void push_stack( stack * s, void * v ) {
48 node * n = malloc( sizeof(node) ); /***/
49 *n = (node){ v, s->head }; /***/
50 s->head = n;
51}
52void * pop_stack( stack * s ) {
53 node * n = s->head;
54 s->head = n->next;
55 void * v = n->value;
56 free( n );
57 return v;
58}
59\end{cfa}
60
61\section{\CFA{}}
62
63\begin{cfa}
64forall( otype T ) {
65 struct node {
66 T value;
67 node(T) * next;
68 };
69 struct stack { node(T) * head; };
70 void ?{}( stack(T) & s, stack(T) t ) { // copy
71 node(T) ** cr = &s.head;
72 for ( node(T) * nx = t.head; nx; nx = nx->next ) {
73 *cr = alloc();
74 ((*cr)->value){ nx->value };
75 cr = &(*cr)->next;
76 }
77 *cr = 0;
78 }
79 void clear( stack(T) & s ) with( s ) {
80 for ( node(T) * nx = head; nx; ) {
81 node(T) * cr = nx;
82 nx = cr->next;
83 ^(*cr){};
84 free( cr );
85 }
86 head = 0;
87 }
88 void ?{}( stack(T) & s ) { (s.head){ 0 }; }
89 void ^?{}( stack(T) & s) { clear( s ); }
90 stack(T) ?=?( stack(T) & s, stack(T) t ) {
91 if ( s.head == t.head ) return s;
92 clear( s );
93 s{ t };
94 return s;
95 }
96 _Bool empty( const stack(T) & s ) {
97 return s.head == 0;
98 }
99 void push( stack(T) & s, T value ) with( s ) {
100 node(T) * n = alloc();
101 (*n){ value, head };
102 head = n;
103 }
104 T pop( stack(T) & s ) with( s ) {
105 node(T) * n = head;
106 head = n->next;
107 T v = n->value;
108 ^(*n){};
109 free( n );
110 return v;
111 }
112}
113\end{cfa}
114
115\section{\CC{}}
116
117\begin{cfa}
118template<typename T> struct stack {
119 struct node {
120 T value;
121 node * next;
122 node( const T & v, node * n = nullptr ) :
123 value( v ), next( n ) {}
124 };
125 node * head;
126 void copy( const stack<T> & o ) {
127 node ** cr = &head;
128 for ( node * nx = o.head; nx; nx = nx->next ) {
129 *cr = new node{ nx->value }; /***/
130 cr = &(*cr)->next;
131 }
132 *cr = nullptr;
133 }
134 void clear() {
135 for ( node * nx = head; nx; ) {
136 node * cr = nx;
137 nx = cr->next;
138 delete cr;
139 }
140 head = nullptr;
141 }
142 stack() : head( nullptr ) {}
143 stack( const stack<T> & o ) { copy( o ); }
144 ~stack() { clear(); }
145 stack & operator=( const stack<T> & o ) {
146 if ( this == &o ) return *this;
147 clear();
148 copy( o );
149 return *this;
150 }
151 bool empty() const {
152 return head == nullptr;
153 }
154 void push( const T & value ) {
155 head = new node{ value, head }; /***/
156 }
157 T pop() {
158 node * n = head;
159 head = n->next;
160 T v = std::move( n->value );
161 delete n;
162 return v;
163 }
164};
165\end{cfa}
166
167\section{\CCV{}}
168
169\begin{cfa}
170struct stack {
171 struct node {
172 ptr<object> value;
173 node * next;
174 node( const object & v, node * n = nullptr ) :
175 value( v.new_copy() ), next( n ) {}
176 };
177 node * head;
178 void copy( const stack & o ) {
179 node ** cr = &head;
180 for ( node * nx = o.head; nx; nx = nx->next ) {
181 *cr = new node{ *nx->value }; /***/
182 cr = &(*cr)->next;
183 }
184 *cr = nullptr;
185 }
186 void clear() {
187 for ( node * nx = head; nx; ) {
188 node * cr = nx;
189 nx = cr->next;
190 delete cr;
191 }
192 head = nullptr;
193 }
194 stack() : head( nullptr ) {}
195 stack( const stack & o ) { copy( o ); }
196 ~stack() { clear(); }
197 stack & operator=( const stack & o ) {
198 if ( this == &o ) return *this;
199 clear();
200 copy( o );
201 return *this;
202 }
203 bool empty() const {
204 return head == nullptr;
205 }
206 void push( const object & value ) {
207 head = new node{ value, head }; /***/
208 }
209 ptr<object> pop() {
210 node * n = head;
211 head = n->next;
212 ptr<object> v = std::move( n->value );
213 delete n;
214 return v;
215 }
216};
217\end{cfa}
Note: See TracBrowser for help on using the repository browser.