@@ -11,123 +11,125 @@ function analyzeMemoryUsage() {
11
11
12
12
// Test data
13
13
const simpleData = { foo : { bar : 'baz' } } ;
14
- const arrayData = { items : Array . from ( { length : 1000 } , ( _ , i ) => ( {
15
- id : i ,
16
- name : `item${ i } ` ,
17
- price : i * 10 ,
18
- tags : [ `tag${ i } ` , `category${ i % 10 } ` ]
19
- } ) ) } ;
20
- const nestedData = { level1 : { level2 : { level3 : { level4 : { value : 42 } } } } } ;
14
+ const arrayData = {
15
+ items : Array . from ( { length : 1000 } , ( _ , i ) => ( {
16
+ id : i ,
17
+ name : `item${ i } ` ,
18
+ price : i * 10 ,
19
+ tags : [ `tag${ i } ` , `category${ i % 10 } ` ] ,
20
+ } ) ) ,
21
+ } ;
22
+ const _nestedData = { level1 : { level2 : { level3 : { level4 : { value : 42 } } } } } ;
21
23
22
24
function measureMemory ( name , fn , iterations = 10000 ) {
23
25
// Force GC before measurement
24
26
global . gc ( ) ;
25
27
const startMemory = process . memoryUsage ( ) ;
26
-
28
+
27
29
const startTime = process . hrtime . bigint ( ) ;
28
30
for ( let i = 0 ; i < iterations ; i ++ ) {
29
31
fn ( ) ;
30
32
}
31
33
const endTime = process . hrtime . bigint ( ) ;
32
-
34
+
33
35
// Force GC after operations
34
36
global . gc ( ) ;
35
37
const endMemory = process . memoryUsage ( ) ;
36
-
38
+
37
39
const memoryDelta = {
38
40
heapUsed : endMemory . heapUsed - startMemory . heapUsed ,
39
41
heapTotal : endMemory . heapTotal - startMemory . heapTotal ,
40
42
external : endMemory . external - startMemory . external ,
41
- rss : endMemory . rss - startMemory . rss
43
+ rss : endMemory . rss - startMemory . rss ,
42
44
} ;
43
-
45
+
44
46
const timeMs = Number ( endTime - startTime ) / 1000000 ;
45
47
const avgTimePerOp = timeMs / iterations ;
46
48
const memoryPerOp = memoryDelta . heapUsed / iterations ;
47
-
49
+
48
50
console . log ( `${ name } :` ) ;
49
51
console . log ( ` Time: ${ timeMs . toFixed ( 2 ) } ms (${ avgTimePerOp . toFixed ( 4 ) } ms/op)` ) ;
50
52
console . log ( ` Memory per operation: ${ memoryPerOp . toFixed ( 2 ) } bytes` ) ;
51
53
console . log ( ` Total heap delta: ${ ( memoryDelta . heapUsed / 1024 / 1024 ) . toFixed ( 2 ) } MB` ) ;
52
54
console . log ( ` Operations/sec: ${ ( iterations / ( timeMs / 1000 ) ) . toFixed ( 0 ) } ` ) ;
53
55
console . log ( '' ) ;
54
-
56
+
55
57
return { memoryPerOp, avgTimePerOp, opsPerSec : iterations / ( timeMs / 1000 ) } ;
56
58
}
57
59
58
60
// Parsing memory analysis
59
61
console . log ( '=== PARSING MEMORY ANALYSIS ===' ) ;
60
-
62
+
61
63
measureMemory ( 'Simple Expression Parse' , ( ) => {
62
64
jmespath . compile ( 'foo.bar' ) ;
63
65
} ) ;
64
-
66
+
65
67
measureMemory ( 'Complex Expression Parse' , ( ) => {
66
68
jmespath . compile ( 'items[?price > `500`].name' ) ;
67
69
} ) ;
68
-
70
+
69
71
measureMemory ( 'Deep Nesting Parse' , ( ) => {
70
72
jmespath . compile ( 'level1.level2.level3.level4.value' ) ;
71
73
} ) ;
72
-
74
+
73
75
measureMemory ( 'Function Call Parse' , ( ) => {
74
76
jmespath . compile ( 'sort_by(items, &price)' ) ;
75
77
} ) ;
76
78
77
79
// Evaluation memory analysis
78
80
console . log ( '=== EVALUATION MEMORY ANALYSIS ===' ) ;
79
-
81
+
80
82
measureMemory ( 'Simple Field Access' , ( ) => {
81
83
jmespath . search ( simpleData , 'foo.bar' ) ;
82
84
} ) ;
83
-
85
+
84
86
measureMemory ( 'Array Projection' , ( ) => {
85
87
jmespath . search ( arrayData , 'items[*].name' ) ;
86
88
} ) ;
87
-
89
+
88
90
measureMemory ( 'Filter Projection' , ( ) => {
89
91
jmespath . search ( arrayData , 'items[?price > `500`].name' ) ;
90
92
} ) ;
91
-
93
+
92
94
measureMemory ( 'Function Call' , ( ) => {
93
95
jmespath . search ( arrayData , 'length(items)' ) ;
94
96
} ) ;
95
-
97
+
96
98
measureMemory ( 'Complex Function' , ( ) => {
97
99
jmespath . search ( arrayData , 'sort_by(items, &price)' ) ;
98
100
} ) ;
99
101
100
102
// Token allocation analysis
101
103
console . log ( '=== TOKEN ALLOCATION ANALYSIS ===' ) ;
102
-
104
+
103
105
measureMemory ( 'Simple Tokenization' , ( ) => {
104
106
jmespath . tokenize ( 'foo.bar' ) ;
105
107
} ) ;
106
-
108
+
107
109
measureMemory ( 'Complex Tokenization' , ( ) => {
108
110
jmespath . tokenize ( 'items[?price > `500` && contains(tags, `"category1"`)].name' ) ;
109
111
} ) ;
110
112
111
113
// Combined parse + eval analysis
112
114
console . log ( '=== COMBINED PARSE + EVAL ANALYSIS ===' ) ;
113
-
115
+
114
116
measureMemory ( 'Full Pipeline Simple' , ( ) => {
115
117
jmespath . search ( simpleData , 'foo.bar' ) ;
116
118
} ) ;
117
-
119
+
118
120
measureMemory ( 'Full Pipeline Complex' , ( ) => {
119
121
jmespath . search ( arrayData , 'items[?price > `500`].name' ) ;
120
122
} ) ;
121
123
122
124
// Pre-compiled vs fresh parse comparison
123
125
console . log ( '=== PRE-COMPILED VS FRESH PARSE ===' ) ;
124
-
126
+
125
127
const compiledExpr = jmespath . compile ( 'items[?price > `500`].name' ) ;
126
-
128
+
127
129
measureMemory ( 'Fresh Parse + Eval' , ( ) => {
128
130
jmespath . search ( arrayData , 'items[?price > `500`].name' ) ;
129
131
} ) ;
130
-
132
+
131
133
measureMemory ( 'Pre-compiled Eval' , ( ) => {
132
134
jmespath . TreeInterpreter . search ( compiledExpr , arrayData ) ;
133
135
} ) ;
0 commit comments