Think carefully about which event code needs to be executed. For instance an AI can probably update his action every second rather then every step. With a room speed of 30 this is a huge optimalisation. But even having something being calculated every other step saves 50% of your coding already. Just move the code from the step event to an alarm event and at the end of the alarm event set the alarm to 2 steps.
You should avoid using the step event as much as possible. The same goes for the drawing event. Note that the drawing event is executed every step for every view you use. So if you have 3 views and a room speed of 60 that means that your code is executed 180 times per second. Drawing goes reasonably fast within GM6 but as the code is being executed very often you still need to try and optimalise it. If something only needs to be drawn in view0 then use: if view_current=0 then draw_sprite(sprite,image,x,y); this way you save 66% of the drawing event by not drwawing this within the other three views.
Game Maker has the ability to temporary disable an object. That means that no event of the object will be executed any longer. This saves you drastically on processing times. Also you can easely destroy all objects that leave the room. These objects stay existing and will keep performing events and even if you still need them later on in the game you can disable several actions for them when not visible. For instance an object outside the screen does not need to be visible. So you can disable visible which disables the drawing event of the object. Also you can disable the AI of the object in most cases as most of the time you do not need to have units being busy which you won't meet for an additional half hour. For instance in a platform game you don't need to have the AI work from left to right and back again until you are close enough to them. Watch out with disabling all objects outside the view/room though and make sure you do not accidently disable for instance a controller object. Also note that functions to count objects will not count disabled objects. So if you end the game when there are no longer any objects you need a special method for detecting this as disabled objects are not recognised.
As has been discussed before, the drawing code is executed for every view you have defined in your view. So try to limit the number of views. Also it is logical that if you keep the room_speed down that you will have less problems with lag within your game as less code needs to be processed per step. You can also make your games go faster by using small rooms. The less objects that are in a room the faster the game goes. You can quite often devide a level up into multiple rooms. With a bit of good timing you can even program it to slide to the next room and have the new room look the same so you do not notice that you enter the new room. This can for instance be done by having a long corridor which you have both in the first and second room. With good timing the player will never notice it switched rooms. Also you can for instance disable the drawing of a background color if you are using a view. This saves you another bit of drawing work. Also you can easely use tiles instead of objects for things like ground. In that case you only need to add objects to the borders of blocks rather then fill the entire block with objects as well. The less objects there are the faster the game goes.