Home > Mobile >  if/else within reduce function is slowing down result time
if/else within reduce function is slowing down result time

Time:11-20

I have a reduce function in my Vue app which works perfectly as far as the logic is concerned but it's incredibly slow.

Luckily, I experimented and found that it's the if/else at the bottom causing the bottleneck (noticable with thousands of records). If I take out the section noted below, it runs quickly.

Should I plug that portion into a different function and just call it at the end of the reduce, or is there another way (that's not obvious to me) that will keep things clean and functional?

<script>
const reduceFunction = (rows) =>
  rows .reduce(
    (a, row) => {
      const employee = a [row .employee] || (a [row .employee] = {dates: {}, total_categories:0, total_items: 0, area: '', group: ''})
      const date = employee .dates [row .itemDate] || (employee .dates [row .itemDate] = {categories: 0, qty: 0, total_categories: 0, unavailable: 0, orders: {}})

      date.categories  =  row.categories_per_item *  row.qty
      date.qty  =  row.qty

      date.total_categories = date.categories

      const order = date .orders [row .order_number] || (date .orders [row .order_number] = {itemDate: '', skus: {}})

      order.itemDate = row.itemDate;

      const sku = order .skus [row .sku] || (order .skus [row .sku] = {categories: '', qty: '', itemDate: '', expected: '', created: '', unavailable: 0, available:0})

      sku.categories  = row.categories_per_item
      sku.qty  = row.qty
      sku.itemDate = row.itemDate
      sku.expected = row.shipDate
      sku.created = row.created_date
      sku.heir_id = row.heir_identifier

      employee.total_categories  = ( row.categories_per_item *  row.qty)
      employee.total_items  = ( row.qty)
      employee.area = row.area
      employee.group = row.group_name
      employee.warehouse = row.warehouse 
      employee.locale = row.locale


      const foundKit = vm.$data.kitsData.find((kit) => kit.heir_identifier === sku.heir_id)

      if (foundKit) {

        new_avail = 10;

        if(sku.qty > new_avail){
          status.status = "Not available";
          date.unavailable  = 1
          sku.unavailable  = 1
        }else{
          status.status = "Available"
        }
      }else{
        status.status = "No item found"
      }

      return a
    },
    {}
  );


var vm = 
new Vue({
  el: "#app",

  data: {
    rows: [
            {  
                employee: "Adam",
                sku: "A1453",
                categories_per_item: "15",
                area: "1",
                itemDate: "2021-11-02",
                qty: 37,
                group_name: "managers",
                warehouse: "3",
                order_number: "1234",
                locale: "1",
                shipDate: "2020-02-02",
                created_date: "2020-01-01",
                heir_identifier:"ABC3"
            },
            {  
                employee: "Joan",
                sku: "A1453",
                categories_per_item: "15",
                area: "1a",
                itemDate: "2021-11-02",
                qty: 17,
                group_name: "managers",
                warehouse: "3",
                order_number: "34578",
                locale: "1",
                shipDate: "2020-02-02",
                created_date: "2020-01-01",
                heir_identifier:"ABC3"
            },
            {  
                employee: "Bill",
                sku: "A1453",
                categories_per_item: "15",
                area: "1",
                itemDate: "2021-11-03",
                qty: 57,
                group_name: "managers",
                warehouse: "3",
                order_number: "2345",
                locale: "1",
                shipDate: "2020-02-02",
                created_date: "2020-01-01",
                heir_identifier:"ABC3"
            },
            {  
                employee: "PJ",
                sku: "A6512",
                categories_per_item: "150",
                area: "2",
                itemDate: "2021-11-03",
                qty: 20,
                group_name: "managers",
                warehouse: "3",
                order_number: "34567",
                locale: "1",
                shipDate: "2020-02-02",
                created_date: "2020-01-01",
                heir_identifier:"ABC1"
            }
        ]
  },
  methods: {

  },

  computed: {
    employeeData() {
      console.log('employee data')
      employeeRows = reduceFunction(this.rows)
      return employeeRows
      console.log(employeeRows)
    },

    dates() {
      return Array.from(Array(11), (_, i) => new Date(Date.now()   i * 86400000).toISOString().slice(0,10))
    }
    
  }
});


</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<div id="app">
<tr v-for="(value, employee) in employeeData"  :key="employee">
  <td>@{{employee}}</td>
  <td v-for="date in dates" :key="date" >
    <div v-for="(dateInfo, dateValue) in value.dates" :key="dateValue" >
      <div v-if="dateValue == date ">
       
        @{{ dateInfo.total_categories }}
      
      </div>
    </div>
  </td>
</tr>
</div>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

CodePudding user response:

It's almost certainly the find() that's the bottleneck, not the if.

Create a Set containing all the heir identifiers, then you can quickly check if the current identifier exists.

const reduceFunction = (rows) => {
  let heirs = new Set(vm.$data.kitsData.map(kit => kit.heir_identifier));
  return rows.reduce(
    (a, row) => {
      const employee = a[row.employee] || (a[row.employee] = {
        dates: {},
        total_categories: 0,
        total_items: 0,
        area: '',
        group: ''
      })
      const date = employee.dates[row.itemDate] || (employee.dates[row.itemDate] = {
        categories: 0,
        qty: 0,
        total_categories: 0,
        unavailable: 0,
        orders: {}
      })

      date.categories  =  row.categories_per_item *  row.qty
      date.qty  =  row.qty

      date.total_categories = date.categories

      const order = date.orders[row.order_number] || (date.orders[row.order_number] = {
        itemDate: '',
        skus: {}
      })

      order.itemDate = row.itemDate;

      const sku = order.skus[row.sku] || (order.skus[row.sku] = {
        categories: '',
        qty: '',
        itemDate: '',
        expected: '',
        created: '',
        unavailable: 0,
        available: 0
      })

      sku.categories  = row.categories_per_item
      sku.qty  = row.qty
      sku.itemDate = row.itemDate
      sku.expected = row.shipDate
      sku.created = row.created_date
      sku.heir_id = row.heir_identifier

      employee.total_categories  = ( row.categories_per_item *  row.qty)
      employee.total_items  = ( row.qty)
      employee.area = row.area
      employee.group = row.group_name
      employee.warehouse = row.warehouse
      employee.locale = row.locale

      if (heirs.has(sku.heir_id) {

          new_avail = 10;

          if (sku.qty > new_avail) {
            status.status = "Not available";
            date.unavailable  = 1
            sku.unavailable  = 1
          } else {
            status.status = "Available"
          }
        } else {
          status.status = "No item found"
        }

        return a
      }, {}
    )
  }
};


var vm =
  new Vue({
    el: "#app",

    data: {
      rows: [{
          employee: "Adam",
          sku: "A1453",
          categories_per_item: "15",
          area: "1",
          itemDate: "2021-11-02",
          qty: 37,
          group_name: "managers",
          warehouse: "3",
          order_number: "1234",
          locale: "1",
          shipDate: "2020-02-02",
          created_date: "2020-01-01",
          heir_identifier: "ABC3"
        },
        {
          employee: "Joan",
          sku: "A1453",
          categories_per_item: "15",
          area: "1a",
          itemDate: "2021-11-02",
          qty: 17,
          group_name: "managers",
          warehouse: "3",
          order_number: "34578",
          locale: "1",
          shipDate: "2020-02-02",
          created_date: "2020-01-01",
          heir_identifier: "ABC3"
        },
        {
          employee: "Bill",
          sku: "A1453",
          categories_per_item: "15",
          area: "1",
          itemDate: "2021-11-03",
          qty: 57,
          group_name: "managers",
          warehouse: "3",
          order_number: "2345",
          locale: "1",
          shipDate: "2020-02-02",
          created_date: "2020-01-01",
          heir_identifier: "ABC3"
        },
        {
          employee: "PJ",
          sku: "A6512",
          categories_per_item: "150",
          area: "2",
          itemDate: "2021-11-03",
          qty: 20,
          group_name: "managers",
          warehouse: "3",
          order_number: "34567",
          locale: "1",
          shipDate: "2020-02-02",
          created_date: "2020-01-01",
          heir_identifier: "ABC1"
        }
      ]
    },
    methods: {

    },

    computed: {
      employeeData() {
        console.log('employee data')
        employeeRows = reduceFunction(this.rows)
        return employeeRows
        console.log(employeeRows)
      },

      dates() {
        return Array.from(Array(11), (_, i) => new Date(Date.now()   i * 86400000).toISOString().slice(0, 10))
      }

    }
  });
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<div id="app">
  <tr v-for="(value, employee) in employeeData" :key="employee">
    <td>@{{employee}}</td>
    <td v-for="date in dates" :key="date">
      <div v-for="(dateInfo, dateValue) in value.dates" :key="dateValue">
        <div v-if="dateValue == date ">

          @{{ dateInfo.total_categories }}

        </div>
      </div>
    </td>
  </tr>
</div>
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

  • Related