How to speed up the code execution?

I have two Views SwitchWorkspace and Home, it takes 2-3 seconds to go from SwitchWorkspace to Home view. I am sharing my views code, I need ideas to speed up the process.

Below is my views.py:

class SwitchWorkspace(LoginRequiredMixin, FormView):
    success_url = reverse_lazy("home")
    template_name = "accounts/switch-workspace.html"
    context = {"title": "Switch workspace"}

    def get(self, request: HttpRequest, *args, **kwargs) -> HttpResponse:
        if request.user.is_superuser:
            return redirect(self.success_url)

        USER_WORKSPACES = request.user.get_workspaces_choices()

        request.session["workspaces"] = USER_WORKSPACES

        form = SwitchWorkspaceForm(request)

        self.context = {"form": form}

        return render(request, self.template_name, self.context)

    def post(self, request: HttpRequest, *args, **kwargs) -> HttpResponse:
        if request.user.is_superuser:
            return redirect(self.success_url)
            
        form = SwitchWorkspaceForm(request, request.POST)

        context = {"form": form}

        if not form.is_valid():
            messages.error(request, "You must select a field")

            return render(request, self.template_name, context)

        form_data = form.cleaned_data

        choice = form_data["workspaces"]

        workspace = Workspace.objects.get(name=choice)

        if not workspace.is_active:
            raise BadRequest("WORKSPACE INACTIVE: We are sorry but the workspace you are trying to \
                                switch to, is inactive. Please ask Administrator to make it active \
                                or try switching to another workspace.")

        workspace_membership = WorkspaceMembership.objects.get(members=request.user, workspaces=workspace)

        if not workspace_membership.is_active:
            raise BadRequest("ACCOUNT INACTIVE: We are sorry but your account for this workspace is inactive. \
                                Please ask your Workspace Administrator to make your account active in this \
                                workspace, or try switching to another workspace.")

        if workspace_membership.is_workspace_admin:
            request.session["is_workspace_admin"] = True

        request.user.update_active_workspace(choice, workspace_membership)

        return redirect(self.success_url)


class Home(LoginRequiredMixin, View):
    template_name = "accounts/home.html"

    def get(self, request: HttpRequest, *args, **kwargs) -> HttpResponse:
        user = request.user

        if user.active_workspace == "w" and not user.is_superuser:
            return redirect(reverse_lazy("switch_workspace"))

        try:
            del request.session['workspaces']
        except KeyError:
            pass

        context = {"title": "Welcome " + request.user.email}

        workspace = Workspace.objects.get(name=user.active_workspace)
        workspace_membership = WorkspaceMembership.objects.get(members=user, workspaces=workspace)

        try:
            context["is_workspace_admin"] = workspace_membership.is_workspace_admin
        except KeyError:
            if request.user.is_superuser:
                return render(request, self.template_name, context)

        return render(request, self.template_name, context)

Any ideas will be appreciated to speed up the process

Are you saying that the delay is occurring after a workspace has been selected and the form as been posted back to the server? (In other words, the delay is occurring in the post method of SwitchWorkspace?

You can use the Django Debug Toolbar to help identify where the time is being spent in this process.

You don’t show the update_active_workspace method in your post here, so that’s one area to look.

Yes the delay is occurring in the post method of SwitchWorkspace View.

Well, the update_active_workspace method is below:

def update_active_workspace(self, workspace: str, workspace_membership: 'WorkspaceMembership'):
        self.active_workspace = workspace
        workspace_membership.last_login = timezone.now()
        if workspace_membership.is_workspace_admin:
            self.user_permissions.clear()
            self.user_permissions.add(*Permission.objects.filter(name__icontains=workspace))
            self.user_permissions.add(*Permission.objects.filter(name__endswith="workspace").exclude(
                name__endswith="delete workspace"
            ))
            self.user_permissions.add(*Permission.objects.filter(name__endswith="user").exclude(
                name__endswith="delete user"
            ))

        workspace_membership.save()            
        self.save()

Any help in speed up the code execution?

Have you installed and used Django Debug Toolbar as suggested to help identify the root cause? If so, what did you find?

1 Like

Follow-up note on this - when looking to get performance measurements, you also don’t want to just take the first use. Go through your app a couple times, making sure most reasonable code paths have been encountered to allow Django and PostgreSQL to propulate their internal caches.

Then run your tests.

Looking at the first result of a system that you’ve just started up is not representative of how that application will work in a production environment.

I am using SQLite, not PostgreSQL in my local computer.

Are you planning on using that as your production database when it’s deployed?

If not, then any performance studies are premature.

No, I will be using MySQL in production and I am using PostgreSQL in testing mode (temporarily deployed on heroku). The speed issue I raised is being faced in both the local computer and in the testing mode.

@KenWhitesell I just installed Django Debug Toolbar. Can you tell me which factor should I see to measure the speed of website?

It’s not just one area - you may end up looking at most of them to get a complete picture of what’s going on.

But first, I’d generally start with the queries tab. It’ll help identify if you have a specific query that is running long or if you’re generating more queries than expected.