I don't know how much some of these inefficiencies affect time, but...

while (%x <= $nick($chan,0))

... This is inside a nested while loop, so this is calling $nick() repeatedly to find out how many people are in the channel, but it would be more efficient to create a variable above your nested loop, then compare against that variable, since the nick-count isn't going to change while the alias is running. It's probably not as bad as doing like...

while (%line.number <= $lines(filename))

--

if (%banmask iswm $address($nick($chan,%x),5)) var %bl = %bl $nick($chan,%x)

While this is more efficient than using $addtok, this is assuming that there aren't 2 different masks affecting the same nick, and looks like this can result in the same nick appearing multiple times if they match several masks.

--

$gettok($1-,1,32)

... is inefficient. Just use $1

--

It's been a while since I benchmarked it, but $iif is slower than the alternative. But even if not, there's no need to have code which could encounter one of these $iif's multiple times. Just have at the beginning:

var %user User , %is Is | if ($chr(32) isin %bl) var %user Users, %is Are

... and then you can replace

$iif($numtok(%bl,32) < 2,User,Users)

... with %user and ditto for the $iif deciding whether to use Is or Are.

Your code echoing the affected nicks has the potential for executing that $regsubex multiple times if you have bans affecting several query windows.

so instead of repeatedly doing

echo -t $query(%i) regsubex

... instead do

var %affected regsubex

.... and then echo %affected instead of calculating the same string repeatedly.

--

if ($me isin %bl && +q isin $1 ) { mode # set $replace($1-,+,-) }

Please get out of the habit of using as few parenthesis as legally possible. It's going to eventually bite you, such as how skipping the parenthesis can sometimes affect the values filled into $v1 and $v2. Plus, the lack of parenthesis makes your code harder to read. No clue what this 'set' is supposed to do...

--

if ( +I isin $gettok($1-,1,32)) echo $chan $timestamp 08,14 ( $+ $numtok(%bl,32) $iif($numtok(%bl,32) < 2,User,Users) $+ ) $iif($numtok(%bl,32) < 2,is,Are) Invited 04,00 $regsubex(%bl,/(\S+)/g,( $+ \n $+ ) \t) 

Since you originally used $countcs to see if I is within $1, shouldn't it be using isincs here?

So you have 8 if() for these different + and - modes, so if the mode list has each of these used 1 time, and each affecting 1 different nick, then your %bl will contain 8 nicks. But your script will echo 8 lines, each of which is informing the user that there were 8 nicks invited, 8 nicks uninvited etc.

--

Your code always falls through to the bottom and executes that final /haltdef, so there's no need to have 3 of them.

--
you have 2 consecutive "if (%bl) { stuff }" that can all be combined into a single if()...

--

It would help if you had some debug info to report what kind of freezes are encountered/or-not for different conditions. I suspect that the slowness comes from looping through a huge nicklist for each mask in your mode list. It would be more efficient to instead use $ialchan to identify who (if any) of the nicks matches each wildmask. Of course that requires a /who #channel having been done...

If not, it would help to get some debug info to identify which line has most of the freeze in it.