Bitcoin resistance against forged slow chain
Of course, as a result of this approach, timestamps in the forged chain would increase much faster than in the real chain. This would cause the forged chain to be discarded by nodes, as legal blocks must have timestamps less than or equal to current timestamp (plus/minus some tolerance).

Not always. For example, in a time warp attack, it's possible to go as many blocks as you want without advancing the clock at all. See How could a time warp attack be prevented? (You should probably avoid making the same off-by-one error in your code.)
For that reason, Bitcoin nodes do not compare chains by their height. (Although they used to do this.) They calculate the total work in each chain (nChainWork), and compare by that. This is calculated by looking at the number of attempts it would take, on average, to find each block, and summing it. This answer touches on how that's done: How is a blockchain split resolved?

Alice controls a bitcoin node, and has 500,000 blocks in storage. Bob advertises that he has 600,000 blocks, but the last common ancestor has number 1000. Bob's chain is a forged slow chain, but Alice does not know it. Alice wants to download Bob's blocks and check if these are correct.

Bitcoin nodes do tell each other how many blocks they each have, but they don't trust this automatically. Rather, they download all of the blocks and check how much work each block has. This can be done faster if you only download the headers; you can tell how much work a block has without downloading the entire block.