Depends on the lag you are talking about. The MOO is single threaded. So only one task/verb is really being executed at a time. And the MOO switches between these to simulate things executing simultaneously. What follows is my general understanding, and this could be incorrect so feel free (anyone) to correct me. This only happens when you're running MOO code. When you use a built-in (like say, connected_players()) the MOO is going to wait for that function to be executed and return a value before allowing the verb, or any other tasks, to continue running. So built-in operations are 'blocking'.
This isn't a big deal with most stuff, because it's really fast. But when you have things like FileIO, the fileio C code is blocking, and opening files/reading/writing/etc can be time consuming. During the time those functions are running, the MOO is going to be non responsive. Most of the time, this is not even perceptible. But if you had something like a loop that was opening 1000 files, and writing data to them, then closing them, over and over and over, you could start to simulate some lag. Issues with FileIO present themselves, as an example, when the OS is bogged down and isn't handling file operations quickly, which results in the MOO not handling them quickly.
If you are using FileIO, you might look there for some of the lag you are experiencing.
I would also look at unoptimized verb code. Stuff that's doing a lot of operations, in loops. Places where you have a for loop inside a for loop inside a for loop, and the like.
Look for places where you are doing lots of calculations and figure out if you can cache the result so that you aren't redoing those operations.
If you've edited any really low level verbs like :tell or :notify or something on $string_utils that is called really often, those are also places where you could have introduced code that would cause lag under some circumstances.
I tend to benchmark verbs by looking at their tick consumption. If I have to suspend, which means I won't get accurate tick counts, I look at the time it takes to execute the verb. If you have time in milliseconds (I think you are using stunt, so you should?) you can turn that on for your evals, or just assign a variable at the start of your code to the current time, then one at the end to the current time and subtract them, giving you the execution time. This isn't suuuper accurate and it won't return the same result every time as other stuff in your MOO will be taking up ticks and if there is a spike in activity, the time for a specific execution could be longer. So I run a verb 10-20 times and average it all together.
You can also write a wrapper verb that you call. I have a $benchmark utility which has a :time verb, and I pass it an object, the verb I want to test, and the number of executions. And it will execute that verb N times, and return the times they took and an average count, and the tick counts/average (if it doesn't suspend). This can be really good for fine tuning important verbs that you need to execute really fast.
Hope this helps!