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

fix(VSelect): improve selection performance #20937

Merged
merged 5 commits into from
Feb 4, 2025

Conversation

KaelWD
Copy link
Member

@KaelWD KaelWD commented Jan 29, 2025

Description

fixes #20703

Time to run transformIn, primitive values:

Item # Before After After
1k 320ms 56ms 0.5ms
10k 40sec 780ms 1ms
100k 75sec 8ms
1M 125ms

Object values ({ key: i }):

Item # Before After
1k 900ms 33ms
10k 88sec 2.5sec
100k
1M

return-object with item-value set appropriately uses primitive value lookup

Markup:

<template>
  <v-app>
    <v-container>
      <v-autocomplete
        v-model="selectedItems"
        :items="items"
        label="test"
        multiple
      >
        <template #prepend-item>
          <v-list-item @click="selectAll()">
            <v-list-item-title> Select all </v-list-item-title>
          </v-list-item>
        </template>
        <template #selection="{ item, index }">
          <template v-if="selectedItems.length > 5">
            <span v-if="!index">{{ selectedItems.length }}</span>
          </template>
          <template v-else>
            <span v-if="index" class="hint mr-1"> or </span>
            <v-chip
              :style="{ height: '24px' }"
              size="small"
              variant="flat"
              label
            >
              {{ item.title }}
            </v-chip>
          </template>
        </template>
      </v-autocomplete>
    </v-container>
  </v-app>
</template>

<script setup>
  import { ref } from 'vue'

  const selectedItems = ref([])
  const items = Array.from({ length: 10000 }, (_, i) => ({ title: `Item ${i}`, value: i }))

  function selectAll () {
    selectedItems.value =
      items.length === selectedItems.value.length ? [] : items.map(c => c.value)
  }
</script>

@KaelWD KaelWD added this to the v3.7.x milestone Jan 29, 2025
@KaelWD KaelWD self-assigned this Jan 29, 2025
@johnleider
Copy link
Member

  • Is there a reason for valueComparator vs _valueComparator?
  • For selectStrategies, how did you test the differences?
  • It seems that most of the performance boost comes from caching the valueComparator, the other changes don't seem to do much

@KaelWD
Copy link
Member Author

KaelWD commented Jan 30, 2025

  • There was no valueComparator variable in scope already
  • There's no behaviour difference, the map is created in strategy.in in the first place so cloning it for every iteration is just a waste of performance
  • Caching hasNullItem and returnObject is worth 100ms with a million items. new Map(map) takes 24ms with just 100 items. The double filter is pretty quick but might as well save the gc on an array that's going to be thrown away instantly.

@KaelWD KaelWD force-pushed the fix/20703-list-select-performance branch from 9ac1aa6 to c4ba8bf Compare January 30, 2025 05:13
@KaelWD
Copy link
Member Author

KaelWD commented Jan 30, 2025

There's still a O(n^2) deepEqual to find the first selected item index:

const index = displayItems.value.findIndex(
item => model.value.some(s => (props.valueComparator || deepEqual)(s.value, item.value))
)

And a linear search to figure out if we're adding or removing a selection:

const index = model.value.findIndex(selection => (props.valueComparator || deepEqual)(selection.value, item.value))

@KaelWD KaelWD changed the title fix(VList): improve selection performance fix(VSelect): improve selection performance Jan 30, 2025
@KaelWD KaelWD merged commit 08aa9d4 into master Feb 4, 2025
17 of 18 checks passed
@KaelWD KaelWD deleted the fix/20703-list-select-performance branch February 4, 2025 06:09
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.

[Bug Report][3.7.4] v-autocomplete laggy when using "select all"
2 participants