-
Notifications
You must be signed in to change notification settings - Fork 19
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
14 changed files
with
613 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,4 @@ | ||
/target | ||
Cargo.lock | ||
.idea | ||
.DS_Store |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
install-wasm-pack: | ||
curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh | ||
|
||
build-wasm-nodejs: | ||
wasm-pack build --release --target nodejs --out-dir pkg/nodejs --features "wasm" | ||
|
||
test-wasm-on-nodejs: | ||
node examples/wasm/nodejs/app.js | ||
|
||
build-wasm-web: | ||
wasm-pack build --release --target web --out-dir pkg/web --features "wasm" | ||
|
||
test-wasm-on-web-browser: | ||
npx http-server -o /examples/wasm/web/index.html | ||
|
||
build-wasm-bundler: | ||
wasm-pack build --release --target bundler --features "wasm" | ||
|
||
pack: | ||
wasm-pack pack pkg |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
const { get_all_date_recurrences_between } = require('../../../pkg/nodejs/rrule.js'); | ||
|
||
const rule_set = 'DTSTART:20120201T093000Z\nRRULE:FREQ=DAILY'; | ||
const data = get_all_date_recurrences_between( | ||
rule_set, | ||
10, | ||
new Date(2021, 0, 1), | ||
new Date(2023, 0, 1) | ||
); | ||
|
||
console.log(data); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
/node_modules |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
import init, { getAllRecurrencesBetween } from '../../../pkg/web/rrule.js'; | ||
import { tryParseEventRecurrenceRules, createValidDateTimeFromISO, getInstanceStartAt } from './rrule_utils.js'; | ||
|
||
function executeRRulePerformanceTest(ruleSet, after, before, limit) { | ||
var rruleWork = () => { | ||
const rule = new rrule.rrulestr(ruleSet); | ||
const results = rule.between(after, before); | ||
} | ||
return executeWork(rruleWork, "rrule"); | ||
} | ||
async function executeRustRRulePerformanceTest(ruleSet, after, before, limit) { | ||
var rustWork = () => { | ||
const data = getAllRecurrencesBetween(ruleSet, after, before, limit); | ||
} | ||
return executeWork(rustWork, "rust-rrule"); | ||
} | ||
|
||
const performance = window.performance; | ||
|
||
function executeWork(work, framework, rounds = 100) { | ||
const measurements = []; | ||
|
||
for (let round = 0; round < rounds; round++) { | ||
const t0 = performance.now(); | ||
work(); | ||
const t1 = performance.now(); | ||
measurements.push(t1 - t0); | ||
} | ||
|
||
// Calculate mean | ||
const mean = measurements.reduce((a, b) => a + b, 0) / measurements.length; | ||
|
||
// Calculate standard deviation | ||
const standardDeviation = Math.sqrt( | ||
measurements.map(x => Math.pow(x - mean, 2)).reduce((a, b) => a + b) / measurements.length | ||
); | ||
|
||
// Calculate confidence interval (95% confidence level) | ||
const zScore = 1.96; // Z-score for 95% confidence | ||
const marginOfError = zScore * (standardDeviation / Math.sqrt(measurements.length)); | ||
const confidenceInterval = [mean - marginOfError, mean + marginOfError]; | ||
|
||
return `Call to ${framework} took an average of ${mean.toFixed(2)} milliseconds with a 95% confidence interval of (${confidenceInterval[0].toFixed(2)}, ${confidenceInterval[1].toFixed(2)}) milliseconds.`; | ||
} | ||
|
||
async function executePerformanceTests() { | ||
const ruleSet = document.getElementById("ruleSet").value.replaceAll('\\n', '\n'); | ||
const afterDateString = document.getElementById("after").value; | ||
const beforeDateString = document.getElementById("before").value; | ||
const limit = document.getElementById("limit").value; | ||
let after = new Date(afterDateString); | ||
let before = new Date(beforeDateString) | ||
|
||
const wasmInitTimeDiv = document.querySelector("#wasmInitTime"); | ||
|
||
wasmInitTimeDiv.innerHTML = "Loading ..."; | ||
const t0 = performance.now(); | ||
await init(); | ||
const t1 = performance.now(); | ||
wasmInitTimeDiv.innerHTML = (t1 - t0) + " milliseconds."; | ||
|
||
const rustRRuleResultDiv = document.querySelector("#rustRRuleResult"); | ||
rustRRuleResultDiv.innerHTML = "Executing ..."; | ||
rustRRuleResultDiv.innerHTML = await executeRustRRulePerformanceTest(ruleSet, after, before, limit); | ||
|
||
setTimeout(() => { | ||
const rruleResultDiv = document.querySelector("#rruleResult"); | ||
rruleResultDiv.innerHTML = "Executing ..."; | ||
rruleResultDiv.innerHTML = executeRRulePerformanceTest(ruleSet, after, before, limit); | ||
|
||
const matchErrorsDiv = document.querySelector("#matchErrors"); | ||
|
||
// const sourceEvent = { | ||
// startAt: '2023-05-31T20:00:00+05:30', | ||
// startTimeZone: 'Asia/Kolkata', | ||
// recurrence: [ | ||
// // 'DTSTART;TZID=Asia/Kolkata:20230531T200000', | ||
// 'EXDATE;TZID=Asia/Kolkata:20230810T200000', | ||
// 'RRULE:FREQ=DAILY;UNTIL=20230818T143000Z', | ||
// ], | ||
// }; | ||
// | ||
// after = new Date('2023-05-30T00:00:00Z'); | ||
// before = new Date('2023-09-01T00:00:00Z'); | ||
|
||
const sourceEvent = { | ||
startAt: '2019-08-13T15:30:00', | ||
startTimeZone: 'Europe/Moscow', | ||
recurrence: [ | ||
// 'DTSTART;TZID=Europe/Moscow:20190813T153000', | ||
'RRULE:FREQ=DAILY', | ||
], | ||
}; | ||
|
||
after = new Date('2019-06-05T21:00:00Z'); | ||
before = new Date('2022-06-22T20:59:59Z'); | ||
|
||
const event = { | ||
recurrenceRules: sourceEvent.recurrence, | ||
startAt: createValidDateTimeFromISO(sourceEvent.startAt, { | ||
zone: sourceEvent.startTimeZone, | ||
}), | ||
} | ||
|
||
const rruleSet = tryParseEventRecurrenceRules(event, { useStartDate: true }) | ||
|
||
console.log(rruleSet.toString()); | ||
|
||
const dates1 = getAllRecurrencesBetween([ | ||
// `DTSTART;TZID=Asia/Kolkata:20230531T200000`, | ||
'DTSTART;TZID=Europe/Moscow:20190813T153000', | ||
...sourceEvent.recurrence].join('\n'), after, before, limit); | ||
const dates2 = rruleSet.between(after, before); | ||
|
||
console.log(dates1, dates2); | ||
|
||
let isFullMatch = true; | ||
|
||
for (let i = 0; i < dates1.length; i++) { | ||
let d1 = dates1.at(i); | ||
let d2 = dates2.at(i); | ||
|
||
d1 = d1 ? new Date(d1) : null; | ||
d2 = getInstanceStartAt(d2, event.startAt).toJSDate(); | ||
|
||
if (d1?.getTime() !== d2?.getTime()) { | ||
matchErrorsDiv.innerHTML += `<li>Dates do not match at index ${i}: ${d1?.toISOString()} !== ${d2?.toISOString()}</li>`; | ||
isFullMatch = false; | ||
} | ||
} | ||
|
||
if (isFullMatch) { | ||
matchErrorsDiv.innerHTML = `All dates match! (${dates1.length})`; | ||
} | ||
}); | ||
} | ||
|
||
document.addEventListener("DOMContentLoaded", () => { | ||
const performanceButton = document.querySelector("#performanceButton"); | ||
|
||
performanceButton.addEventListener("click", () => { | ||
executePerformanceTests(); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<meta content="text/html;charset=utf-8" http-equiv="Content-Type"/> | ||
<meta http-equiv="cache-control" content="max-age=0" /> | ||
<meta http-equiv="cache-control" content="no-cache" /> | ||
<script type="module" src="./node_modules/rrule/dist/es5/rrule.js"></script> | ||
<script type="module" src="./benchmarking.js"></script> | ||
</head> | ||
<body> | ||
<h1>rust-rrule x rrule</h1> | ||
|
||
<label for="ruleSet">RuleSet:</label> | ||
<textarea id="ruleSet" name="ruleSet" cols="150" rows="8"> | ||
DTSTART;TZID=Europe/Moscow:20190813T153000 | ||
RRULE:FREQ=DAILY | ||
RDATE;TZID=Europe/Moscow:20190813T153000 | ||
</textarea> | ||
|
||
<br><br> | ||
|
||
<label for="after">After:</label> | ||
<input type="text" id="after" name="after" value="2019-06-05T21:00:00Z"><br><br> | ||
|
||
<label for="before">Before:</label> | ||
<input type="text" id="before" name="before" value="2022-06-22T20:59:59Z"><br><br> | ||
|
||
<label for="limit">Date Recurrences Limit:</label> | ||
<input type="text" id="limit" name="limit" value="730"><br><br> | ||
|
||
<button id="performanceButton">Calculate Performance</button> | ||
|
||
<br><br><br> | ||
<label>Result:</label> | ||
<div>WASM init time: <span id="wasmInitTime">...</span></div> | ||
<div id="rustRRuleResult">No rust-rrule results yet</div> | ||
<div id="rruleResult">No rrule results yet</div> | ||
<div>Match: <span id="matchErrors">...</span></div> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
{ | ||
"name": "rrule-wasm", | ||
"dependencies": { | ||
"rrule": "latest", | ||
"luxon": "latest" | ||
} | ||
} |
Oops, something went wrong.