Skip to content

Slow performance when merging cookies #783

@Kludex

Description

@Kludex

Originally opened by @gyula-lakatos on 2023-10-02 17:16:44 in encode/httpx

  • Initially raised as discussion #2874

There is a quite significant performance degradation when cookies are being used with requests.

httpx._client.BaseClient._merge_cookies calls into the cookiejar here:

        if cookies or self.cookies:
            merged_cookies = Cookies(self.cookies)
            merged_cookies.update(cookies)
            return merged_cookies
        return cookies

When either cookies or self.cookies is not None, then httpx._models.Cookies.__bool__ will call into a method called deepvalues in http.cookiejar.CookieJar by indirectly calling http.cookiejar.CookieJar.__iter__.

httpx._models.Cookies.__bool__:

    def __bool__(self) -> bool:
        for _ in self.jar:
            return True
        return False

http.cookiejar.CookieJar.__iter__:

    def __iter__(self):
        return deepvalues(self._cookies)

Deepvalues is a significant performance hog because it does a lot of things recursively.

A suggested solution is to check cookies and self.cookies to None instead of using __bool__.

I dropped a performance snapshot to illustrate the problem:
image

Here deepvalues takes up almost 17% of the CPU time.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions