github.com/stealthrocket/wzprof@v0.2.1-0.20230830205924-5fa86be5e5b3/testdata/c/bench.c (about) 1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 #include <sys/time.h> 5 6 int64_t now() { 7 struct timeval tv; 8 gettimeofday(&tv, NULL); 9 return ((int64_t)(tv.tv_sec))*1e9 + ((int64_t)(tv.tv_usec))*1e3; 10 } 11 12 int isAbs(const char *path) { 13 return *path == '/'; 14 } 15 16 int isDir(const char *path) { 17 const int n = strlen(path); 18 return (n > 0) && path[n-1] == '/'; 19 } 20 21 int appendCleanPath(char *buf, int bufLen, const char *path, int *lookupParent) { 22 while (*path) { 23 while (*path && *path == '/') { 24 path++; 25 } 26 27 const char *ptr = path; 28 const char *end = path; 29 while (*end && *end != '/') { 30 end++; 31 } 32 path = end; 33 34 const int len = end - ptr; 35 if (len == 0) { 36 continue; 37 } 38 39 if (len == 1 && ptr[0] == '.') { 40 continue; 41 } 42 43 if (len == 2 && ptr[0] == '.' && ptr[1] == '.') { 44 if (!*lookupParent) { 45 int k = bufLen; 46 while (k > 0 && buf[k-1] != '/') { 47 k--; 48 } 49 while (k > 1 && buf[k-1] == '/') { 50 k--; 51 } 52 bufLen = k; 53 if (k == 0) { 54 *lookupParent = 1; 55 } else { 56 continue; 57 } 58 } 59 } else { 60 *lookupParent = 0; 61 } 62 63 if (bufLen > 0 && buf[bufLen-1] != '/') { 64 buf[bufLen] = '/'; 65 bufLen++; 66 } 67 memmove(buf + bufLen, ptr, len); 68 bufLen += len; 69 } 70 return bufLen; 71 } 72 73 char *joinPath(const char *dir, const char *file) { 74 int bufSize = strlen(dir) + strlen(file) + 8; 75 int bufLen = 0; 76 char *buf = malloc(bufSize); 77 memset(buf, 0, bufSize); 78 if (isAbs(dir)) { 79 buf[0] = '/'; 80 bufLen++; 81 } 82 int lookupParent = 0; 83 bufLen = appendCleanPath(buf, bufLen, dir, &lookupParent); 84 bufLen = appendCleanPath(buf, bufLen, file, &lookupParent); 85 if (bufLen == 0) { 86 buf[0] = '.'; 87 bufLen++; 88 } 89 if (buf[bufLen-1] != '/' && isDir(file)) { 90 buf[bufLen] = '/'; 91 } 92 return buf; 93 } 94 95 int main(int argc, char **argv) { 96 if (argc > 4) { 97 puts("usage: join [dir] [file]"); 98 return 2; 99 } 100 101 const char *cmd = "join"; 102 const char *dir = "."; 103 const char *file = "."; 104 if (argc > 1) { 105 cmd = argv[1]; 106 } 107 if (argc > 2) { 108 dir = argv[2]; 109 } 110 if (argc > 3) { 111 file = argv[3]; 112 } 113 114 if (strcmp(cmd, "join") == 0) { 115 puts(joinPath(dir, file)); 116 } else if (strcmp(cmd, "test") == 0) { 117 const int n = atoi(argv[2]); 118 puts("goos:"); 119 puts("goarch:"); 120 puts("pkg:"); 121 122 for (int i = 0; i < n; i++) { 123 const int64_t start = now(); 124 const int64_t count = 20e6; 125 126 for (int64_t j = 0; j < count; j++) { 127 free(joinPath(dir, file)); 128 } 129 130 const int64_t end = now(); 131 printf("BenchmarkJoinPath/#00 %lld\t% 10.2f ns/op\n", count, ((double)(end - start))/count); 132 fflush(stdout); 133 } 134 135 puts("PASS"); 136 } else { 137 puts("usage: join|test"); 138 return 2; 139 } 140 return 0; 141 }