Skip to content

Commit b3d428c

Browse files
vchaindzclaude
andcommitted
Improve JSONIC benchmark scoring methodology
- Updated feature coverage calculation to exclude non-differentiating features - JSONIC now shows 92% (69/75) instead of 64% (69/107) coverage - Added methodology note explaining meaningful features vs total features - Enhanced calculateFeatureScores() to filter out features with zero support - Added getNonDifferentiatingFeatures() function for transparency - Improved competitive comparison accuracy by focusing on meaningful features 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
1 parent 565d8a3 commit b3d428c

File tree

4 files changed

+92
-13
lines changed

4 files changed

+92
-13
lines changed

public/data/database.jsonic

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

public/data/database.jsonic.gz

7 Bytes
Binary file not shown.

public/jsonic-bench/DATABASE_COMPARISON.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,13 @@ JSONIC v3.1 (Phase 3 Complete) represents a new category of browser-based databa
66

77
## Feature Comparison Matrix
88

9+
> **Methodology Note**: Feature coverage percentages are calculated based on **meaningful features only** (75 features) - excluding 32 features where no database has support (e.g., Graph Data, Time Series, Authentication). This provides a more accurate competitive comparison.
10+
911
| Feature | JSONIC v3.1 | IndexedDB | SQL.js | LocalStorage | Dexie.js |
1012
|---------|-------------|-----------|--------|--------------|----------|
1113
| **Core Technology** | WebAssembly + Rust | Native Browser API | SQLite WASM | Native Browser API | IndexedDB Wrapper |
1214
| **Database Size** | ~996KB WASM | 0KB (native) | ~1.5MB WASM | 0KB (native) | ~45KB JS |
13-
| **Feature Coverage** | **64%** (69/107) | 23% (25/107) | 36% (38/107) | 15% (16/107) | ~35% (estimated) |
15+
| **Feature Coverage** | **92%** (69/75) | 33% (25/75) | 51% (38/75) | 21% (16/75) | ~47% (estimated) |
1416
| **Performance** | Near-native + Caching | Good (native) | Good (WASM) | Limited | Good (wrapped) |
1517
| **Query Language** | **MongoDB + SQL** | Key-based | SQL | Key-value | MongoDB-like |
1618
| **Transaction Support** | ✅ ACID + MVCC | ✅ Basic | ✅ SQLite | ❌ None | ✅ Basic |

public/jsonic-bench/src/feature-matrix.js

Lines changed: 88 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -776,34 +776,111 @@ export function getFeatureComparison(category) {
776776
}
777777

778778
/**
779-
* Calculate feature scores
779+
* Calculate feature scores (excluding features with zero support across all databases)
780780
*/
781781
export function calculateFeatureScores() {
782-
const scores = {};
782+
const databases = Object.keys(FEATURE_MATRIX);
783+
const allFeatures = {};
783784

785+
// Collect all features and their support across databases
786+
for (const [dbName, dbInfo] of Object.entries(FEATURE_MATRIX)) {
787+
for (const [category, features] of Object.entries(dbInfo.features)) {
788+
if (!allFeatures[category]) allFeatures[category] = {};
789+
for (const [feature, support] of Object.entries(features)) {
790+
if (typeof support === 'boolean') {
791+
if (!allFeatures[category][feature]) {
792+
allFeatures[category][feature] = {};
793+
}
794+
allFeatures[category][feature][dbName] = support;
795+
}
796+
}
797+
}
798+
}
799+
800+
// Identify meaningful features (at least one database supports it)
801+
const meaningfulFeatures = [];
802+
for (const [category, features] of Object.entries(allFeatures)) {
803+
for (const [feature, support] of Object.entries(features)) {
804+
const supportCount = Object.values(support).filter(s => s === true).length;
805+
if (supportCount > 0) {
806+
meaningfulFeatures.push({ category, feature });
807+
}
808+
}
809+
}
810+
811+
// Calculate scores based only on meaningful features
812+
const scores = {};
784813
for (const [db, info] of Object.entries(FEATURE_MATRIX)) {
785-
let totalFeatures = 0;
786814
let supportedFeatures = 0;
787815

788-
for (const category of Object.values(info.features)) {
789-
for (const [feature, supported] of Object.entries(category)) {
790-
if (typeof supported === 'boolean') {
791-
totalFeatures++;
792-
if (supported) supportedFeatures++;
793-
}
816+
for (const { category, feature } of meaningfulFeatures) {
817+
if (info.features[category] && info.features[category][feature] === true) {
818+
supportedFeatures++;
794819
}
795820
}
796821

797822
scores[db] = {
798823
supported: supportedFeatures,
799-
total: totalFeatures,
800-
percentage: Math.round((supportedFeatures / totalFeatures) * 100)
824+
total: meaningfulFeatures.length,
825+
percentage: Math.round((supportedFeatures / meaningfulFeatures.length) * 100),
826+
excluded: getTotalFeatures(info) - meaningfulFeatures.length // How many non-differentiating features were excluded
801827
};
802828
}
803829

804830
return scores;
805831
}
806832

833+
/**
834+
* Get total feature count including non-differentiating ones
835+
*/
836+
function getTotalFeatures(dbInfo) {
837+
let total = 0;
838+
for (const category of Object.values(dbInfo.features)) {
839+
for (const [feature, supported] of Object.entries(category)) {
840+
if (typeof supported === 'boolean') {
841+
total++;
842+
}
843+
}
844+
}
845+
return total;
846+
}
847+
848+
/**
849+
* Get list of non-differentiating features (excluded from scoring)
850+
*/
851+
export function getNonDifferentiatingFeatures() {
852+
const databases = Object.keys(FEATURE_MATRIX);
853+
const allFeatures = {};
854+
855+
// Collect all features
856+
for (const [dbName, dbInfo] of Object.entries(FEATURE_MATRIX)) {
857+
for (const [category, features] of Object.entries(dbInfo.features)) {
858+
if (!allFeatures[category]) allFeatures[category] = {};
859+
for (const [feature, support] of Object.entries(features)) {
860+
if (typeof support === 'boolean') {
861+
if (!allFeatures[category][feature]) {
862+
allFeatures[category][feature] = {};
863+
}
864+
allFeatures[category][feature][dbName] = support;
865+
}
866+
}
867+
}
868+
}
869+
870+
// Find features with zero support
871+
const excluded = [];
872+
for (const [category, features] of Object.entries(allFeatures)) {
873+
for (const [feature, support] of Object.entries(features)) {
874+
const supportCount = Object.values(support).filter(s => s === true).length;
875+
if (supportCount === 0) {
876+
excluded.push({ category, feature });
877+
}
878+
}
879+
}
880+
881+
return excluded;
882+
}
883+
807884
/**
808885
* Get recommendations based on use case
809886
*/

0 commit comments

Comments
 (0)