home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #19 / NN_1992_19.iso / spool / comp / lang / perl / 5524 < prev    next >
Encoding:
Text File  |  1992-08-26  |  3.0 KB  |  98 lines

  1. Path: sparky!uunet!cs.utexas.edu!usc!news!netlabs!lwall
  2. From: lwall@netlabs.com (Larry Wall)
  3. Newsgroups: comp.lang.perl
  4. Subject: Re: Fast String Operations?
  5. Message-ID: <1992Aug27.002721.1322@netlabs.com>
  6. Date: 27 Aug 92 00:27:21 GMT
  7. References: <1992Aug25.151625.3134@IDA.ORG>
  8. Sender: news@netlabs.com
  9. Organization: NetLabs, Inc.
  10. Lines: 85
  11. Nntp-Posting-Host: scalpel.netlabs.com
  12.  
  13. In article <1992Aug25.151625.3134@IDA.ORG> rlg@IDA.ORG (Randy garrett) writes:
  14. : I'm looking for the fastest way to perform the following operation.
  15. : Basically, this is a conversion of one database format to another.
  16. : If I have a NULL field, indicated by 2 pipe symbols next to
  17. : each other, I want to insert either a -1 or a ~ between the 
  18. : two pipes, depending upon whether the type of that field
  19. : is a integer or a character.  I know the type of the field
  20. : because I've already pre-filled that array with the correct
  21. : types from the Data Dictionary (Thanks Sybase to Perl Interface!).
  22. : So, I read in a series of lines from a file.  If I find 2 pipe 
  23. : symbols adjacent to each other, "||", in the input string, I want
  24. : to insert either a ~  or a -1 depending on the type of that field,
  25. : which I get from the @name array.
  26.  
  27. There's a very important piece of information that you left out.  Namely,
  28. what percentage of the lines do you expect will have a null field?  If
  29. many lines don't have null fields, you want to say this:
  30.  
  31.     while (<INPUT>) {
  32.     next unless /\|\|/;
  33.     # replacement algorithm goes here
  34.     }
  35.  
  36. This sort of short circuit can save you oodles of time, regardless of
  37. how inefficient your replacement algorithm is.  Presuming, of course,
  38. that most lines will be rejected immediately.
  39.  
  40. If most lines have null fields, then it's a waste of time to do the
  41. short circuit, and you can just go straight for one of the split
  42. methods previously posted (preferably the correct one).
  43.  
  44. Alternately, (there's always an alternately) you can do something
  45. fancy like this:
  46.  
  47.     #!/usr/bin/perl
  48.  
  49.     $/ = '|';
  50.     @default = (-1,'~',-1,-1,'~',-1,'~',-1);
  51.  
  52.     while (<>) {
  53.     $field = 0, print "\n" if s/^\n//;
  54.     next unless /^\|/;
  55.     print $default[$field];
  56.     }
  57.     continue {
  58.     print;
  59.     ++$field;
  60.     }
  61.  
  62. This presumes there's always a | right before the "\n".  It seemed from
  63. your description that this is so, but it wasn't explicit.
  64.  
  65. Anyhoo, try them out on your data, and see which one is faster.  I can't
  66. predict without seeing the data.
  67.  
  68. By the way.  Just between you and me and the gatepost, this *might*
  69. be a better job for C than for Perl, if you only have to support this
  70. on one architecture.  C is better than Perl at character crawling:
  71.  
  72.     #include <stdio.h>
  73.  
  74.     char *def[] = {"-1","~","-1","-1","~","-1","~","-1"};
  75.  
  76.     main() {
  77.     int ch;
  78.     int lastch;
  79.     int field = 0;
  80.  
  81.     while ((ch = getc(stdin)) != EOF) {
  82.         if (ch == '\n')
  83.         field = 0;
  84.         else if (ch == '|') {
  85.         if (lastch == '|')
  86.             fputs(def[field], stdout);
  87.         field++;
  88.         }
  89.         putc(ch, stdout);
  90.         lastch = ch;
  91.     }
  92.     }
  93.  
  94. Or sumph'n like that.
  95.  
  96. Larry
  97.