Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Perform minimal type checking for dictSet function, #5456

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

hummy123
Copy link
Contributor

@hummy123 hummy123 commented Feb 26, 2025

What is the problem/goal being addressed?

There's a performance problem with the dictSet function: the dictionary is a map, which we convert to a list, only for the dictionary type-checking function to convert it back to a map.

Suboptimal performance comes from two things:

  1. Converting a map to a list, only to convert the list back to a map (and adding one key).
  2. Type checking every single element in the dictionary, which is unnecessary because we accept that the map is type safe as a prerequisite for the dictSet function.

What is the solution to this problem?

I think we can perform fewer operations while upholding type safety.

  1. Get any key/value pair from the map (preferably without searching the whole map).
  2. Compare the types of the old key/value pairvwith the new key/value pair we wish to insert
  3. If the old pair and the new pair have the same types, insert them into the existing map (else, raise an error)

No need to check the type of every single element, or convert the map to a list, which are both O(n) operations.

What are the changes here? How do they solve the problem and what other product impacts do they cause?

Commit only contains changes to a bit of purely functional code, and all the Dict.set tests which passed before still pass now.

I also added two new tests, adding different key/value pairs to empty dictionaries.

Has this information been included in the comments?

The general idea is commented.

Other notes

I wanted to add a test to check if a type error is raised when we:

  1. Remove everything from a (string, int) dictionary
  2. Set a key/value pair of some different type like (string, string)

but I wasn't sure how to write multi-line tests as there didn't seem to be any in the files I looked at. I think my code won't introduce any regression in that regard because it passes the exact same arguments to the type-checking function, except the list to type-check is shorter.

As an alternative to this approach, if we want to type check N elements but not to covert the whole map to a list, we can call Maq.toSeq and iterate through a number of elements smaller than the length of the map, but I'm not sure what we gain with that approach.

@hummy123 hummy123 marked this pull request as ready for review February 27, 2025 12:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant