I know you asked for ideas but i feel this idea is hard to show without code, I often do this to ensure my code runs smoother with out having to make checks for things like the hash table existing and being loaded etc etc
Simply instead of refrencing the hash table by name you create a identifier alias that returns the hashtable name, if also creates it and loads it up if it doesnt exist., this allows you to, if u had such reason to , replace the saved version, and /hfree the table, the next time any script refrences it, the table is created and loaded from disk again.

I also moved the /hsave straight after the /hadd, IMO this is better, even if more disk intensive although im doing them all the time recording stuff of very active channels and hsaving the table and i dont notice any delay likely windows is just caching it up.

Code:
#greet on 
alias -l greet {
  if (!$hget(greet)) {
    hmake -s greet 100
    if ($isfile(greet.hsh) == $true) hload -s greet greet.hsh }
  return greet
}
on !*:join:#channelnamehere: { 
  if ($hfind($greet, $nick)) { msg $chan $nick $+ : $hget($greet, $nick) } 
  else { msg $chan !greet <your greeting here> and i will greet you with that every time you join. } 
} 
on *:text:!greet *:#channelnamehere: {
  hadd -s $greet $nick $2- 
  hsave -so $greet greet.hsh 
  var %greeting = $hget($greet,$nick) 
  msg $chan $nick $+ 's greeting was set to: %greeting 
} 
#greet end 


I also did the code so to show how you can reduce the code using $greet (if not the actual amount of code that gets run)

PS: i used $greet at all points but truth be told, you only need it on the first refrence to the hashtable in any script section, after that you can just use GREET if you liked, but i think thats haphazard unless you know the code wont ever get altered.

I wouldnt use $site or $address kinda my personal beleieve that people change em alot.