Hace exactamente lo que dice, agrupa todos tus sprites (dibujos individuales) en una sola llamada de dibujo. Para explicarlo mejor te diré cómo LibGDX utiliza OpenGL para dibujar cosas en el lienzo virtual.
Cada sprite se dibuja creando un quad (plano) en el espacio 3D. Esta malla quad contiene 4 vértices y cada vértice contiene datos de vértice como coordenadas de posición y textura. Normalmente se construyen/manipulan estos datos en la CPU y cuando se está listo para dibujar se envían a la GPU. La apertura de esta conexión entre la CPU y la GPU es relativamente lenta y, por lo tanto, la forma más eficiente es agrupar todos estos datos y enviarlos en tantas comunicaciones de vista (llamadas de dibujo) como sea posible.
El SpriteBatch es una clase que hace este trabajo por ti. Cada vez que llamas a draw(), en lugar de dibujar en la pantalla, añade los vértices de tu quad a un buffer. Cuando el buffer está lleno o llamas a end() envía todos los datos a la GPU. Por defecto el buffer puede contener 1000 quads/espíritus pero puedes especificar tu propio tamaño hasta 8191 quads/espíritus, lo cual es una limitación sólo porque SpriteBatch usa primitivas cortas para especificar los índices de los quads. Si realmente necesitas dibujar más sprites a la vez en una sola llamada puedes hacer tu propio SpriteBatch, pero 8191 quads repartidos equitativamente en una resolución de 1080p significa que cada quad contiene sólo un par de docenas de píxeles. Así que si eres inteligente al respecto, un solo SpriteBatch es suficiente para la mayoría de los juegos.
Otra cosa a tener en cuenta es que si estás usando una textura diferente en un sprite, también se lavará y enviará los datos a la GPU con el fin de vincular la nueva textura. Llamar a draw() 4 veces en el orden de textura1 -> textura2 -> textura1 -> textura2 creará 4 llamadas de dibujo donde textura1 -> textura1 -> textura2 -> textura2 creará sólo 2 llamadas de dibujo. Una forma fácil de reducir las llamadas de dibujo en este caso es usar un TextureAtlas/spritesheet donde tienes muchas imágenes individuales una al lado de la otra en una textura grande. Si tienes una gran cantidad de estas texturas y no puedes reducir la conmutación tienes la opción de rodar tu propio SpriteBatch y shader. Esta tarea parece desalentadora pero en realidad es bastante trivial. Echa un vistazo a la clase SpriteBatch por ti mismo, todo lo que hace el método draw() es añadir datos de vértices a un array y cuando se llama a flush() estos datos se ponen en una malla que realmente se está dibujando. Si puedes dibujar un quad con textura simple puedes crear tu propio SpriteBatch también.