glBegin()/glEnd() and displaylists are part of the deprecated "immediate mode" pipeline.
The preferred method now is to use vertex buffer objects.
The difference between these two methods is that in immediate mode, each time through the render loop, you are transferring vertex data from host memory to the GPU, even if you are using display lists (display lists are maintained on the host and not the display card).
A vertex buffer object is a memory buffer that is maintained in the memory of the display card. You set it up once, then transfer your vertex data all at once before you start rendering. Then each time through the render loop, you call specialized drawing functions that tell the display card to draw using data from that buffer, thus avoiding the need to perform costly host to display card data transfers.
Using vertex buffer objects requires a bit more set-up than immediate mode rendering, but the speed-up is well worth it. Google opengl vertex buffer objects. There should be plenty of tutorials and example code to get you started.