There is a big difference between the code as we see it, and the code that is actually executed in the background: queries are evaluated, resulting in code that is actually executed.
I regard this as the M(agic) of Power Query and accepted as fact that you just don't know what is really happening in the background.
As an example, in case of Direct Query with Query Folding (that is: if you have a database with a database management system as data source), an entire query definition is translated into 1 SQL-statement that is fired to the database and executed by the database management system, which will only return the resulting data.
These are the fastest queries.
For the execution time, it doesn't matter if you have many query steps, or if you combine the code of multiple steps into 1 step.
Some recommendations if direct query/query folding is not applicable:
1. Referring to a table row, using an index (e.g. Table1{Index}) is time consuming.
If you want to refer to data on the previous row, it is better to add 2 Index columns - 1 starting with 1 and the other with 0 - and merge the table with itself on these index columns.
This way, you will get the data on the same row, which will be much faster.
2. Before any looping (using List.Accumulate, List.Generate or recursive functions), buffer the table using Table.Buffer.
With recursive functions involving table transformations, you should also buffer the table at each iteration.
3. If you want to perform approximate lookups, it is much faster to transform the lookup table in a buffered list of lists and use that to perform the approximate lookups.
You can find an interesting discussion on
TechNet.
4. It seems that DAX tends to be faster than Power Query.
These are the examples I can think of, but I'm sure there will be other recommendations.