Fri Oct 14 19:43:59 2016 UTC ()
A small optimization: since we already know the length of the lines, check
if the lenghts are equal before calling strcmp(3). Most of the times, the call
to strcmp(3) can be saved if the lines are not of the same length.

Thanks to Christos for the reviews


(abhinav)
diff -r1.18 -r1.19 src/usr.bin/uniq/uniq.c

cvs diff -r1.18 -r1.19 src/usr.bin/uniq/uniq.c (expand / switch to unified diff)

--- src/usr.bin/uniq/uniq.c 2012/08/26 14:14:16 1.18
+++ src/usr.bin/uniq/uniq.c 2016/10/14 19:43:59 1.19
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: uniq.c,v 1.18 2012/08/26 14:14:16 wiz Exp $ */ 1/* $NetBSD: uniq.c,v 1.19 2016/10/14 19:43:59 abhinav Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1989, 1993 4 * Copyright (c) 1989, 1993
5 * The Regents of the University of California. All rights reserved. 5 * The Regents of the University of California. All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to Berkeley by 7 * This code is derived from software contributed to Berkeley by
8 * Case Larsen. 8 * Case Larsen.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -32,54 +32,55 @@ @@ -32,54 +32,55 @@
32 * SUCH DAMAGE. 32 * SUCH DAMAGE.
33 */ 33 */
34 34
35#include <sys/cdefs.h> 35#include <sys/cdefs.h>
36#ifndef lint 36#ifndef lint
37__COPYRIGHT("@(#) Copyright (c) 1989, 1993\ 37__COPYRIGHT("@(#) Copyright (c) 1989, 1993\
38 The Regents of the University of California. All rights reserved."); 38 The Regents of the University of California. All rights reserved.");
39#endif /* not lint */ 39#endif /* not lint */
40 40
41#ifndef lint 41#ifndef lint
42#if 0 42#if 0
43static char sccsid[] = "@(#)uniq.c 8.3 (Berkeley) 5/4/95"; 43static char sccsid[] = "@(#)uniq.c 8.3 (Berkeley) 5/4/95";
44#endif 44#endif
45__RCSID("$NetBSD: uniq.c,v 1.18 2012/08/26 14:14:16 wiz Exp $"); 45__RCSID("$NetBSD: uniq.c,v 1.19 2016/10/14 19:43:59 abhinav Exp $");
46#endif /* not lint */ 46#endif /* not lint */
47 47
48#include <err.h> 48#include <err.h>
49#include <errno.h> 49#include <errno.h>
50#include <stdio.h> 50#include <stdio.h>
51#include <ctype.h> 51#include <ctype.h>
52#include <stdlib.h> 52#include <stdlib.h>
53#include <string.h> 53#include <string.h>
54#include <unistd.h> 54#include <unistd.h>
55 55
56static int cflag, dflag, uflag; 56static int cflag, dflag, uflag;
57static int numchars, numfields, repeats; 57static int numchars, numfields, repeats;
58 58
59static FILE *file(const char *, const char *); 59static FILE *file(const char *, const char *);
60static void show(FILE *, const char *); 60static void show(FILE *, const char *);
61static const char *skip(const char *); 61static const char *skip(const char *, size_t *);
62static void obsolete(char *[]); 62static void obsolete(char *[]);
63static void usage(void) __dead; 63static void usage(void) __dead;
64 64
65int 65int
66main (int argc, char *argv[]) 66main (int argc, char *argv[])
67{ 67{
68 const char *t1, *t2; 68 const char *t1, *t2;
69 FILE *ifp, *ofp; 69 FILE *ifp, *ofp;
70 int ch; 70 int ch;
71 char *prevline, *thisline, *p; 71 char *prevline, *thisline, *p;
72 size_t prevlinesize, thislinesize, psize; 72 size_t prevlinesize, thislinesize, psize;
 73 size_t prevlinecompsize, thislinecompsize;
73 74
74 setprogname(argv[0]); 75 setprogname(argv[0]);
75 ifp = ofp = NULL; 76 ifp = ofp = NULL;
76 obsolete(argv); 77 obsolete(argv);
77 while ((ch = getopt(argc, argv, "-cdf:s:u")) != -1) 78 while ((ch = getopt(argc, argv, "-cdf:s:u")) != -1)
78 switch (ch) { 79 switch (ch) {
79 case '-': 80 case '-':
80 --optind; 81 --optind;
81 goto done; 82 goto done;
82 case 'c': 83 case 'c':
83 cflag = 1; 84 cflag = 1;
84 break; 85 break;
85 case 'd': 86 case 'd':
@@ -134,38 +135,40 @@ done: argc -= optind; @@ -134,38 +135,40 @@ done: argc -= optind;
134 135
135 thislinesize = psize; 136 thislinesize = psize;
136 if ((thisline = malloc(thislinesize + 1)) == NULL) 137 if ((thisline = malloc(thislinesize + 1)) == NULL)
137 err(1, "malloc"); 138 err(1, "malloc");
138 139
139 while ((p = fgetln(ifp, &psize)) != NULL) { 140 while ((p = fgetln(ifp, &psize)) != NULL) {
140 if (psize > thislinesize) { 141 if (psize > thislinesize) {
141 if ((thisline = realloc(thisline, psize + 1)) == NULL) 142 if ((thisline = realloc(thisline, psize + 1)) == NULL)
142 err(1, "realloc"); 143 err(1, "realloc");
143 thislinesize = psize; 144 thislinesize = psize;
144 } 145 }
145 (void)memcpy(thisline, p, psize); 146 (void)memcpy(thisline, p, psize);
146 thisline[psize] = '\0'; 147 thisline[psize] = '\0';
 148 thislinecompsize = thislinesize;
 149 prevlinecompsize = prevlinesize;
147 150
148 /* If requested get the chosen fields + character offsets. */ 151 /* If requested get the chosen fields + character offsets. */
149 if (numfields || numchars) { 152 if (numfields || numchars) {
150 t1 = skip(thisline); 153 t1 = skip(thisline, &thislinecompsize);
151 t2 = skip(prevline); 154 t2 = skip(prevline, &prevlinecompsize);
152 } else { 155 } else {
153 t1 = thisline; 156 t1 = thisline;
154 t2 = prevline; 157 t2 = prevline;
155 } 158 }
156 159
157 /* If different, print; set previous to new value. */ 160 /* If different, print; set previous to new value. */
158 if (strcmp(t1, t2)) { 161 if (thislinecompsize != prevlinecompsize || strcmp(t1, t2)) {
159 char *t; 162 char *t;
160 size_t ts; 163 size_t ts;
161 164
162 show(ofp, prevline); 165 show(ofp, prevline);
163 t = prevline; 166 t = prevline;
164 prevline = thisline; 167 prevline = thisline;
165 thisline = t; 168 thisline = t;
166 ts = prevlinesize; 169 ts = prevlinesize;
167 prevlinesize = thislinesize; 170 prevlinesize = thislinesize;
168 thislinesize = ts; 171 thislinesize = ts;
169 repeats = 0; 172 repeats = 0;
170 } else 173 } else
171 ++repeats; 174 ++repeats;
@@ -185,40 +188,42 @@ static void @@ -185,40 +188,42 @@ static void
185show(FILE *ofp, const char *str) 188show(FILE *ofp, const char *str)
186{ 189{
187 190
188 if ((dflag && repeats == 0) || (uflag && repeats > 0)) 191 if ((dflag && repeats == 0) || (uflag && repeats > 0))
189 return; 192 return;
190 if (cflag) { 193 if (cflag) {
191 (void)fprintf(ofp, "%4d %s", repeats + 1, str); 194 (void)fprintf(ofp, "%4d %s", repeats + 1, str);
192 } else { 195 } else {
193 (void)fprintf(ofp, "%s", str); 196 (void)fprintf(ofp, "%s", str);
194 } 197 }
195} 198}
196 199
197static const char * 200static const char *
198skip(const char *str) 201skip(const char *str, size_t *linesize)
199{ 202{
200 int infield, nchars, nfields; 203 int infield, nchars, nfields;
 204 size_t ls = *linesize;
201 205
202 for (nfields = numfields, infield = 0; nfields && *str; ++str) 206 for (nfields = numfields, infield = 0; nfields && *str; ++str, --ls)
203 if (isspace((unsigned char)*str)) { 207 if (isspace((unsigned char)*str)) {
204 if (infield) { 208 if (infield) {
205 infield = 0; 209 infield = 0;
206 --nfields; 210 --nfields;
207 } 211 }
208 } else if (!infield) 212 } else if (!infield)
209 infield = 1; 213 infield = 1;
210 for (nchars = numchars; nchars-- && *str; ++str) 214 for (nchars = numchars; nchars-- && *str; ++str, --ls)
211 continue; 215 continue;
 216 *linesize = ls;
212 return str; 217 return str;
213} 218}
214 219
215static FILE * 220static FILE *
216file(const char *name, const char *mode) 221file(const char *name, const char *mode)
217{ 222{
218 FILE *fp; 223 FILE *fp;
219 224
220 if ((fp = fopen(name, mode)) == NULL) 225 if ((fp = fopen(name, mode)) == NULL)
221 err(1, "%s", name); 226 err(1, "%s", name);
222 return(fp); 227 return(fp);
223} 228}
224 229