Firstly - check that there is not some CPU-heavy task running on your machine. For the moment I would just write your program, and then worry about if/when it's dropping frames later. If it's still an issue at completion, then optimise it.
One way to speed this up is to pass the rectangle for changed screen area to the pygame.display.update( dirty_rectangle ) function. That way only the part of the screen that has been "dirtied" by changes will be updated. This means that typically a smaller part of the screen will be re-drawn.
I also modified the code to draw the circle to an off-screen surface, and just blit() that image to the screen, rather than re-calculate the circle each loop. That makes it easy to work out the corners of the changed area too.
For your example, it's possible to calculate this rectangle based on the position of the circle, and where it has been previously. So before repositioning the circle to the new co-ordinate, we make a copy of circle_rect into previous_rect. The new position is calculated, the drawing position updated. The maximum extent of the update is then the minimum top-left corner of both rectangles, down to the maximum of the bottom-right corners. The min & max is used to populate the update rectangle.
import pygame
import sys
import math
pygame.init()
screen = pygame.display.set_mode((1920,1080))
clock = pygame.time.Clock()
# Create a sprite for the circle
CIRCLE_RAD=20
circle = pygame.Surface( (CIRCLE_RAD*2, CIRCLE_RAD*2), pygame.SRCALPHA, 32 )
circle.fill( (0,0,0) )
pygame.draw.circle( circle, (255,255,255), (CIRCLE_RAD,CIRCLE_RAD), CIRCLE_RAD )
circle_rect = circle.get_rect()
update_rect = circle_rect.copy()
while True:
for e in pygame.event.get():
if e.type == pygame.QUIT:
sys.exit()
previous_rect = circle_rect.copy()
t = pygame.time.get_ticks()
t800 = t/800
circle_rect.center = ( 960 + 300 * math.cos(t800), 540 + 300 * math.sin(t800) )
# work out the size of the update
min_x = min( previous_rect.x, circle_rect.x )
min_y = min( previous_rect.y, circle_rect.y )
max_x = max( previous_rect.x + previous_rect.width, circle_rect.x + circle_rect.width )
max_y = max( previous_rect.y + previous_rect.height, circle_rect.y + circle_rect.height )
update_rect.update( min( previous_rect.x, circle_rect.x ),
min( previous_rect.y, circle_rect.y ),
max_x-min_x,
max_y-min_y )
screen.fill('Black')
screen.blit( circle, circle_rect )
pygame.display.update( update_rect )
ms_since_previous = clock.tick(60)
if ( ms_since_previous > 17 ): # 60FPS is about 17ms between frames
print( "Slow update: %d milliseconds" % ( ms_since_previous ) )