From: synful@drycas.club.cc.cmu.edu (Marc Shannon)
Newsgroups: news.software.anu-news
Subject: Some (unauthorized) fixes to speed up NEWS
Date: 11 Apr 92 04:46:25 GMT
Organization: Carnegie Mellon Computer Club

In an attempt to speed up NEWS's start-up time, I used PCA to find some of the
heavily used routines and optimize them a bit.  On a VAXstation 4000 VLC
running ANU NEWS V6.1a3, I've managed to get the start-up time reduced from
about 32 seconds down to 20.

The first "fix-up" was in NEWSRC.C (only if you are using the built-in Arbitron
routines) to prevent having to search the entire group list and instead using a
hash-table.  The second was for NEWSUTILITY.C to prevent string comparisons
(and, instead, using a byte-comparison).

--Marc

************
File NEWS_MANAGER_DEV:[NEWS_SRC]NEWSRC.C;165
 1882     };
 1883   
 1884   #define ARB_HASH_SIZE 247
 1885   
 1886   struct arb_record *arb_hash_table[ARB_HASH_SIZE];
 1887   
 1888   int arb_hash(char *grpname)
 1889   {
 1890       int retval = 0;
 1891       char *curchar;
 1892       static int initialized = 0;
 1893   
 1894       if (!initialized)
 1895       {
 1896           for (retval = 0;retval < ARB_HASH_SIZE;retval++)
 1897   	    arb_hash_table[retval] = 0;
 1898   	initialized = 1;
 1899       }
 1900       
 1901       curchar = grpname;
 1902       while (*curchar)
 1903           retval = retval + *(curchar++);
 1904   
 1905       return (retval % ARB_HASH_SIZE);
 1906   }
 1907   
 1908   struct arb_record *hash_find(char *grpname)
 1909   {
 1910       struct arb_record *lookingfor;
 1911       int recordfound;
 1912   
 1913       if (arb_hash_table[arb_hash(grpname)]) {
 1914           lookingfor = arb_hash_table[arb_hash(grpname)];
 1915   	recordfound = (!strcmp(lookingfor->arb_grpname, grpname));
 1916       } else {
 1917   	lookingfor = arb_hash_table[arb_hash(grpname)] =
 1918   	    (struct arb_record *)malloc(sizeof(struct arb_record));
 1919   	lookingfor->arb_grpname = (char *)malloc(strlen(grpname) + 1);
 1920   	strcpy(lookingfor->arb_grpname, grpname);
 1921   	lookingfor->arb_readtime = 0;
 1922   	lookingfor->arb_next = 0;
 1923   	recordfound = 1;
 1924       }
 1925   
 1926       while (!recordfound)
 1927           if (lookingfor->arb_next) {
 1928   	    lookingfor = lookingfor->arb_next;
 1929   	    recordfound = (!strcmp(lookingfor->arb_grpname, grpname));
 1930   	} else {
 1931   	    lookingfor = lookingfor->arb_next =
 1932   		(struct arb_record *)malloc(sizeof(struct arb_record));
 1933   	    lookingfor->arb_grpname = (char *)malloc(strlen(grpname) + 1);
 1934   	    strcpy(lookingfor->arb_grpname, grpname);
 1935   	    lookingfor->arb_readtime = 0;
 1936   	    lookingfor->arb_next = 0;
 1937   	    recordfound = 1;
 1938   	}
 1939   
 1940       return (lookingfor);
 1941   }
 1942   
******
File NEWS_MANAGER_DEV:[NEWS_SRC]NEWSRC.C;162
 1882     } *arb_head = 0, *arb_tail = 0;
 1883   
************
************
File NEWS_MANAGER_DEV:[NEWS_SRC]NEWSRC.C;165
 1947     struct arb_record *tmp;
 1948   
 1949     tmp = hash_find(grpname);
 1950     if (readtime > tmp->arb_readtime) tmp->arb_readtime = readtime;
 1951   }
******
File NEWS_MANAGER_DEV:[NEWS_SRC]NEWSRC.C;162
 1888     struct arb_record *tmp = arb_head;
 1889   
 1890     while (tmp && strcmp(tmp->arb_grpname,grpname)) tmp = tmp->arb_next;
 1891     if (!tmp) {
 1892       tmp = malloc(sizeof *tmp);
 1893       strcpy((tmp->arb_grpname = malloc(strlen(grpname)+1)),grpname);
 1894       tmp->arb_readtime = readtime;
 1895       tmp->arb_next = 0;
 1896       if (arb_tail) {
 1897         arb_tail->arb_next = tmp;
 1898         arb_tail = tmp;
 1899         }
 1900       else arb_head = arb_tail = tmp;
 1901       }
 1902     else if (readtime > tmp->arb_readtime) tmp->arb_readtime = readtime;
 1903   }
************
************
File NEWS_MANAGER_DEV:[NEWS_SRC]NEWSRC.C;165
 1956     struct arb_record *tmp;
 1957   
 1958     tmp = hash_find(grpname);
 1959     if (tmp) return(tmp->arb_readtime);
 1960   }  
******
File NEWS_MANAGER_DEV:[NEWS_SRC]NEWSRC.C;162
 1908     struct arb_record *tmp = arb_head;
 1909   
 1910     while (tmp && strcmp(tmp->arb_grpname,grpname)) tmp = tmp->arb_next;
 1911     if (tmp) return(tmp->arb_readtime);
 1912     return(0);
 1913   }  
************

Number of difference sections found: 3
Number of difference records found: 80

DIFFERENCES /IGNORE=()/MERGED=1/OUTPUT=USR:[SYNFUL]NEWSRC.DIFF;1-
    NEWS_MANAGER_DEV:[NEWS_SRC]NEWSRC.C;165-
    NEWS_MANAGER_DEV:[NEWS_SRC]NEWSRC.C;162

************
File NEWS_MANAGER_DEV:[NEWS_SRC]NEWSUTILITY.C;491
 1700     int i, slen;
 1701   
 1702     slen = strlen(s);
 1703     if (slen >= SUBJLEN)
 1704         slen = SUBJLEN - 1;
 1705     slen = (slen > 0) ? slen - 1 : 0;  
 1706         
 1707   /* This little trick lets us do single byte compares on each newsgroup.
 1708      Assuming that the group for which we are searching has a name of less than
 1709      SUBJLEN characters (#define'd maximum), then slen should be a valid index
 1710      into the character array pointing at the last character.  This essentially
 1711      checks to see if the two group names have the same length. */
 1712   
 1713     for (i = 1; i <= ga_size; ++i)
 1714       if (s[slen] == ga[i]->grp_name[slen])
 1715           if (!strcmp(s, ga[i]->grp_name))
 1716   	    return (i);
 1717     return(0);
******
File NEWS_MANAGER_DEV:[NEWS_SRC]NEWSUTILITY.C;486
 1700     int i;
 1701   
 1702     for (i = 1; i <= ga_size; ++i)
 1703       if (!strcmp(s,ga[i]->grp_name)) return(i);
 1704     return(0);
************

Number of difference sections found: 1
Number of difference records found: 17

DIFFERENCES /IGNORE=()/MERGED=1/OUTPUT=USR:[SYNFUL]NEWSUTILITY.DIFF;1-
    NEWS_MANAGER_DEV:[NEWS_SRC]NEWSUTILITY.C;491-
    NEWS_MANAGER_DEV:[NEWS_SRC]NEWSUTILITY.C;486
Organization: Network Development, Carnegie Mellon, Pittsburgh, PA