From:	MERC::"uunet!VM1.NoDak.EDU!ANU-NEWS" 12-APR-1992 20:34:31.32
To:	Multiple recipients of list ANU-NEWS <ANU-NEWS@VM1.NoDak.EDU>
CC:	
Subj:	Some (unauthorized) fixes to speed up NEWS

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 i
ndex
 1710      into the character array pointing at the last character.  This essent
ially
 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
