GithubHelp home page GithubHelp logo

Comments (4)

davidgoli avatar davidgoli commented on June 12, 2024 4

Yeah, there isn't a great native replacement for Luxon's TZ functionality. Most of the cost is in the dateInTimeZone functionality:

const dateTZtoISO8601 = function (date: Date, timeZone: string) {
  // date format for sv-SE is almost ISO8601
  const dateStr = date.toLocaleString('sv-SE', { timeZone })
  // '2023-02-07 10:41:36'
  return dateStr.replace(' ', 'T') + 'Z'
}

export const dateInTimeZone = function (date: Date, timeZone: string) {
  const localTimeZone = Intl.DateTimeFormat().resolvedOptions().timeZone

  // Date constructor can only reliably parse dates in ISO8601 format
  const dateInLocalTZ = new Date(dateTZtoISO8601(date, localTimeZone))
  const dateInTargetTZ = new Date(dateTZtoISO8601(date, timeZone ?? 'UTC'))
  const tzOffset = dateInTargetTZ.getTime() - dateInLocalTZ.getTime()

  return new Date(date.getTime() - tzOffset)
}

I see a 25% speed up by moving this line to the top-level scope:

const localTimeZone = Intl.DateTimeFormat().resolvedOptions().timeZone

So that's worth doing. Will have to investigate more to see what else can be sped up.

from rrule.

newOlli avatar newOlli commented on June 12, 2024 1

Hello!

I'm having the same problem. After doing some research, I discovered the following:

Rule1 : freq=DAILY;dtstart;TZID=Europe/Helsinki:20200102T020000;interval=1;byweekday=MO,TU,WE,TH,FR,SA,SU;
Rule2 : freq=DAILY;tzid=Europe/Helsinki;interval=1;byweekday=MO,TU,WE,TH,FR,SA,SU;byhour=2;byminute=0;bysecond=0;

Although both rules provide the same dates, Rule 1 takes 681 ms locally and Rule 2 takes 0.79ms.

I then discovered that the between call takes longer if the rules dtstart and betweens parameter after are far apart.
For instance, the call is relatively quick if I have a rule with 1.1.2020 as the start date and I call between 1.1.2021 and 1.2.2021 as the after and before dates.
However, using 1.1.2030 and 1.2.2030 as betweens parameters causes the function to execute quite slowly.
This is only noticeable if TZID is defined in the rule. The call still takes longer if TZID is not defined, but the difference is not as bad.

I am using rule 2.8.1 with the test code below but the same problem is also in 2.7.2.

import { performance } from "perf_hooks";
import { rrulestr } from "rrule";

function rruleGenerateDates(rulesting: string, customAfterDate?: Date) {
  const rule = rrulestr(rulesting);

  if (customAfterDate) {
    const before = new Date();
    before.setDate(customAfterDate.getDate() + 1 * 7);
    let dates = rule.between(customAfterDate, before);
  } else {
    let dates = rule.between(new Date("2022-04-04T10:00"), new Date("2023-04-04T11:00"));
  }
}

// Set the number of runs.
const runs = 100;

// Function to benchmark a function.
async function benchmark(func: (rule: string, customAfterDate?: Date) => any, rule: string, runs: number, customAfterDate?: Date) {
  let start = performance.now();

  for (let i = 0; i < runs; i++) {
    await func(rule, customAfterDate);
  }

  let end = performance.now();

  return (end - start) / runs;
}

async function runBenchmark(runs: number) {
  cconst ruleWithStartTime = `freq=DAILY\ndtstart;TZID=Europe/Helsinki:20200102T020000\ninterval=1\nbyweekday=MO,TU,WE,TH,FR,SA,SU`;
  let duration = await benchmark(rruleGenerateDates, ruleWithStartTime, runs);
  console.log(`With start time average time: ${duration} ms`);
  const ruleWithoutStartTime = `freq=DAILY\ntzid=Europe/Helsinki\ninterval=1\nbyweekday=MO,TU,WE,TH,FR,SA,SU\nbyhour=2\nbyminute=0\nbysecond=0`;
  duration = await benchmark(rruleGenerateDates, ruleWithoutStartTime, runs);
  console.log(`Without start time average time: ${duration} ms`);

  console.log("Same rule but difference in betweens after parameter:");
  duration = await benchmark(rruleGenerateDates, ruleWithStartTime, runs, new Date("2060-09-30"));
  console.log(`2060 after date average time: ${duration} ms`);
  duration = await benchmark(rruleGenerateDates, ruleWithStartTime, runs, new Date("2021-09-30"));
  console.log(`2021 after date average time: ${duration} ms`);
}
//With start time average time: 681.4148922994733 ms
//Without start time average time: 0.735097499936819 ms
//Same rule but difference in betweens after parameter:
//2060 after date average time: 8109.418215399981 ms
//2021 after date average time: 750.5864615000785 ms
runBenchmark(10);

from rrule.

dorfman avatar dorfman commented on June 12, 2024

Looks like the Luxon dependency was removed in PR #508 to reduce load times in-browser. Luxon is really good at handling timezones, especially when compared to the native Date library. So that’s a bummer.

from rrule.

W0lfEagle avatar W0lfEagle commented on June 12, 2024

Also noticed huge performance issues. We're seeing vast improvements by using the rrule-rust package.

from rrule.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.