]> git.draconx.ca Git - cdecl99.git/commitdiff
Batch up crossparse tests to improve performance.
authorNick Bowler <nbowler@draconx.ca>
Sat, 3 Mar 2012 03:30:15 +0000 (22:30 -0500)
committerNick Bowler <nbowler@draconx.ca>
Sat, 3 Mar 2012 03:33:33 +0000 (22:33 -0500)
A significant portion of the crossparse test time is spent just starting
the program hundreds of times.  Batch up the random declarations to
reduce this.  This makes the test script somewhat more complex, but the
gain is significant: the test time (500 iterations) on my machine is
shortened from 7 seconds to a mere .7 seconds.

test/crossparse.c
tests/crossparse-c-random.sh

index 75344cb6d911e7529e5aff0bdfaedfaf250829d8..f377c38142c2ae54644d0874cf4d80250ffe062f 100644 (file)
@@ -2,6 +2,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <stdbool.h>
 #include <getopt.h>
 #include <cdecl.h>
 #include "test.h"
 #include <getopt.h>
 #include <cdecl.h>
 #include "test.h"
@@ -69,9 +70,44 @@ err:
 }
 #define rerender(str, p, r) (rerender(str, #p, p, #r, r))
 
 }
 #define rerender(str, p, r) (rerender(str, #p, p, #r, r))
 
-int main(int argc, char **argv)
+static bool test_crossparse(const char *str, int mode)
 {
        char *buf1 = NULL, *buf2 = NULL, *buf3 = NULL;
 {
        char *buf1 = NULL, *buf2 = NULL, *buf3 = NULL;
+       bool ret = false;
+
+       if (mode == MODE_ENGLISH) {
+               buf1 = rerender(str, cdecl_parse_english, cdecl_declare);
+               if (!buf1)
+                       goto out;
+               buf2 = rerender(buf1, cdecl_parse_decl, cdecl_explain);
+               if (!buf2)
+                       goto out;
+               buf3 = rerender(buf2, cdecl_parse_english, cdecl_declare);
+               if (!buf3)
+                       goto out;
+       } else {
+               buf1 = rerender(str, cdecl_parse_decl, cdecl_explain);
+               if (!buf1)
+                       goto out;
+               buf2 = rerender(buf1, cdecl_parse_english, cdecl_declare);
+               if (!buf2)
+                       goto out;
+               buf3 = rerender(buf2, cdecl_parse_decl, cdecl_explain);
+               if (!buf3)
+                       goto out;
+       }
+
+       if (!strcmp(buf1, buf3))
+               ret = true;
+out:
+       free(buf1);
+       free(buf2);
+       free(buf3);
+       return ret;
+}
+
+int main(int argc, char **argv)
+{
        int opt, mode = MODE_CDECL;
        int ret = EXIT_FAILURE;
 
        int opt, mode = MODE_CDECL;
        int ret = EXIT_FAILURE;
 
@@ -103,33 +139,13 @@ int main(int argc, char **argv)
                return EXIT_FAILURE;
        }
 
                return EXIT_FAILURE;
        }
 
-       if (mode == MODE_ENGLISH) {
-               buf1 = rerender(argv[optind], cdecl_parse_english, cdecl_declare);
-               if (!buf1)
-                       goto out;
-               buf2 = rerender(buf1, cdecl_parse_decl, cdecl_explain);
-               if (!buf2)
-                       goto out;
-               buf3 = rerender(buf2, cdecl_parse_english, cdecl_declare);
-               if (!buf3)
-                       goto out;
-       } else {
-               buf1 = rerender(argv[optind], cdecl_parse_decl, cdecl_explain);
-               if (!buf1)
-                       goto out;
-               buf2 = rerender(buf1, cdecl_parse_english, cdecl_declare);
-               if (!buf2)
-                       goto out;
-               buf3 = rerender(buf2, cdecl_parse_decl, cdecl_explain);
-               if (!buf3)
-                       goto out;
+       for (int i = optind; i < argc; i++) {
+               if (!test_crossparse(argv[i], mode)) {
+                       fprintf(stderr, "%s: failed cross-parse check of: %s\n",
+                                       progname, argv[i]);
+                       return EXIT_FAILURE;
+               }
        }
 
        }
 
-       if (!strcmp(buf1, buf3))
-               ret = EXIT_SUCCESS;
-out:
-       free(buf1);
-       free(buf2);
-       free(buf3);
-       return ret;
+       return EXIT_SUCCESS;
 }
 }
index 8fb1b633039d96d2bc39e66fcb9ed2014b5cb5d8..9fc45fb4b7d6415028d8b8197fa0e545e6e04815 100755 (executable)
@@ -14,19 +14,52 @@ randomdecl=test/randomdecl$EXEEXT
 crossparse=test/crossparse$EXEEXT
 test -x $randomdecl || exit 77
 
 crossparse=test/crossparse$EXEEXT
 test -x $randomdecl || exit 77
 
+# Slow case: run tests one at a time to determine exactly which one failed.
+first_failed() {
+       ff_count=0
+
+       while test $# -gt 0
+       do
+               $crossparse "$1" 2>/dev/null || break
+               ff_count=`expr $ff_count + 1`
+               shift
+       done
+
+       echo "$ff_count"
+}
+
 proc() {
        result=pass
        count=0
 
 proc() {
        result=pass
        count=0
 
+       set x
        while read decl
        do
        while read decl
        do
-               count=`expr $count + 1`
-               $crossparse "$decl" || { result=fail
-                       printf 'original input: %s\n' "$decl" 1>&2
-                       break
+               set "$@" "$decl"
+
+               # Accumulate tests in $@ and run them in batches to avoid
+               # significant startup costs.
+               if test $# -gt 25; then
+                       shift
+                       $crossparse "$@" || { result=fail
+                               tmp_count=`first_failed "$@"`
+                               count=`expr $count + $tmp_count`
+                               break
                        }
                        }
+                       count=`expr $count + $#`
+                       set x
+               fi
        done
 
        done
 
+       shift
+       if test $# -gt 0 && test x"$result" = x"pass"; then
+               tmp_count=$#
+               $crossparse "$@" || { result=fail
+                       tmp_count=`first_failed "$@"`
+               }
+               count=`expr $count + $tmp_count`
+       fi
+
        echo "result=$result"
        echo "count=$count"
 }
        echo "result=$result"
        echo "count=$count"
 }