try this.

Code:
 
alias mp3db.make {
  if (!$hget(mp3)) { ^mp3_load_db }
  if ($hget(mp3,0).item == $findfile($sound(mp3),*.mp?,0)) {
    echo -s -> MP3 DB is up-to-date.
    return
  }
  echo -s -> Updating mp3 database...
  var %ticks $ticks, %a, %b, %str, %idx 0, %temp, %mpeg
  _mp3dirlist
  if ($fopen(myoutput) != $null) fclose myoutput
  fopen myoutput myoutput.txt
  if ($ferr == 0) {
    while ($ferr == 0 && $feof == 0) {
      %temp = $fread(myoutput)
      if ($isfile($gettok(%temp,1,32))) {
        if (!$hget(mp3,$gettok(%temp,1,32))) {
          %a = $gettok(%temp,1,32)
          %b = $gettok(%temp,2,32)
          %mpeg = $mpeginfo(%a)
          tokenize 32 %mpeg
          %str = $+($1,$chr(9),$2,$chr(9),$3,$chr(9),$4-,$chr(9),$lower($bytes(%b).suf))
          .hadd mp3 %a %str
        }
      }
    }
    if ($ferr == 0) {
       if ($fopen(myoutput) != $null) fclose myoutput
      .hsave -ob mp3 $scriptdirmp3.db
      .remove myoutput.txt
      echo -s -> MP3 database updated in $:ms(%ticks) seconds.
    }
  }
  if ($fopen(myoutput) != $null) fclose myoutput
}
 

as thats only a subsection of your code i couldnt run it to test it but i think it looks right.

Here is some things that take up time I changed.

>> while (%idx < $lines(myoutput.txt)) {
the identifier $lines(myoutput.txt) reads the said file from front to end counting the number of lines in it, you do this once per line so you just for the WHILE condition read the file as many times as there are lines in it.

>>%temp = $read(myoutput.txt, nl, %idx)
the identifier $read(myoutput.txt, nl, %idx) reads the said file from front to the line requested, you do this once per line so you read 1/2 the file on average every $READ


What I have done is instead
(1) open the file
(2) check if its at the end of the file ($feof)
(3) if not then read the line im at, process it, then loop back to (2)
(4) finsih up

this well cause one file read, rather than 1.5 entire reads of the file per line processed.


You might consider doing this, but i doubt you well get more than a second per 10,000 lines
>> tokenize 32 $chr(9) %mpeg
>> %str = $+($2,$1,$3,$1,$4,$1,$5-,$1,$lower($bytes(%b).suf))

OR (not and) at the start of the alias adding
>>var %tab = $chr(9)
and making the two lines above like this.
>>tokenize 32 %mpeg
>>%str = $+($1,%tab,$2,%tab,$3,%tab,$4-,%tab,$lower($bytes(%b).suf))

but again i doubt much performance increase on that.