@@ -879,110 +879,126 @@ var _inputFns = new Map([
879879 [ "javagc" , ( _res , options ) => {
880880 if ( ! isBoolean ( params . javagcjoin ) ) params . javagcjoin = toBoolean ( _$ ( params . javagcjoin , "javagcjoin" ) . isString ( ) . default ( __ ) )
881881
882+ // Pre-compile regex patterns for performance (moved outside hot path)
883+ const regexes = [
884+ // JDK 8 Allocation Failure (adjusted to handle multiline events)
885+ / ( [ ^ ] + ) ( \d + \. \d + ) : \[ ( G C ) \( ( .* ?) \) ( .+ ?) \[ P S Y o u n g G e n : ( \d + K ) - > ( \d + K ) \( ( .* ?) \) \] ( \d + K ) - > ( \d + K ) \( ( .* ?) \) , ( \d + \. \d + ) s e c s \] \[ T i m e s : u s e r = ( \d + \. \d + ) s y s = ( \d + \. \d + ) , r e a l = ( \d + \. \d + ) s e c s \] / s,
886+ // JDK 8 style regexes
887+ / ( [ ^ ] + ) ( \d + \. \d + ) : \[ ( G C ) \( ( .* ?) \) \[ P S Y o u n g G e n : ( \d + K ) - > ( \d + K ) \( ( .* ?) \) \] ( \d + K ) - > ( \d + K ) \( ( .* ?) \) , ( \d + \. \d + ) s e c s \] / ,
888+ // JDK 8 with +PrintHeapAtGC
889+ / ( [ ^ ] + ) ( \d + \. \d + ) : \[ ( F u l l G C ) \( ( .* ?) \) \[ P S Y o u n g G e n : ( \d + K ) - > ( \d + K ) \( ( .* ?) \) \] \[ P a r O l d G e n : ( \d + K ) - > ( \d + K ) \( ( .* ?) \) \] ( \d + K ) - > ( \d + K ) \( ( .* ?) \) , \[ M e t a s p a c e : ( \d + K ) - > ( \d + K ) \( ( .* ?) \) \] , ( \d + \. \d + ) s e c s \] \[ T i m e s : u s e r = ( \d + \. \d + ) s y s = ( \d + \. \d + ) , r e a l = ( \d + \. \d + ) s e c s \] / ,
890+ // JDK 8 with +PrintHeapAtGC and +PrintTenuringDistribution
891+ / ( [ ^ ] + ) ( \d + \. \d + ) : \[ ( F u l l G C ) \( ( .* ?) \) \[ P S Y o u n g G e n : ( \d + K ) - > ( \d + K ) \( ( .* ?) \) \] \[ P a r O l d G e n : ( \d + K ) - > ( \d + K ) \( ( .* ?) \) \] ( \d + K ) - > ( \d + K ) \( ( .* ?) \) , \[ M e t a s p a c e : ( \d + K ) - > ( \d + K ) \( ( .* ?) \) \] , ( \d + \. \d + ) s e c s \] / ,
892+ // JDK 8 with +PrintTenuringDistribution
893+ / ( [ ^ ] + ) ( \d + \. \d + ) : \[ ( G C ) \( ( .* ?) \) \[ P S Y o u n g G e n : ( \d + K ) - > ( \d + K ) \( ( .* ?) \) \] ( \d + K ) - > ( \d + K ) \( ( .* ?) \) , ( \d + \. \d + ) s e c s \] \[ T i m e s : u s e r = ( \d + \. \d + ) s y s = ( \d + \. \d + ) , r e a l = ( \d + \. \d + ) s e c s \] / ,
894+ // JDK 8 Generic GC logs (simple format)
895+ / ( \d + \. \d + ) : \[ ( G C | F u l l G C ) \( ( .* ?) \) \s + ( \d + K ) - > ( \d + K ) \( ( \d + K ) \) , ( \d + \. \d + ) s e c s \] / ,
896+ // JDK 9+ style regexes
897+ / ^ \[ ( .+ ) \] \s + G C \( ( \d + ) \) \s * ( .* ?) \s * ( \d + [ G M K ] ) - > ( \d + [ G M K ] ) \( ( \d + [ G M K ] ) \) \s * ( \d + \. \d + ) m s / ,
898+ / ^ \[ ( .+ ) \] \s + G C \( ( \d + ) \) \s * ( .* ?) \s * M e t a s p a c e : \s * ( \d + [ G M K ] ) \( ( \d + [ G M K ] ) \) - > ( \d + [ G M K ] ) \( ( \d + [ G M K ] ) \) \s * N o n C l a s s : \s * ( \d + [ G M K ] ) \( ( \d + [ G M K ] ) \) - > ( \d + [ G M K ] ) \( ( \d + [ G M K ] ) \) \s * C l a s s : \s * ( \d + [ G M K ] ) \( ( \d + [ G M K ] ) \) - > ( \d + [ G M K ] ) \( ( \d + [ G M K ] ) \) / ,
899+ // JDK 9+ Allocation Failure
900+ / ^ \[ ( .+ ) \] \s + G C \( ( \d + ) \) \s * ( A l l o c a t i o n F a i l u r e ) \s * ( .* ?) \s + ( \d + [ K M G T ] ) - > ( \d + [ K M G T ] ) \( ( \d + [ K M G T ] ) \) \s + ( \d + \. \d + ) m s / ,
901+ ]
902+
903+ // Pre-compile patterns for head parsing
904+ const timePattern = / ^ \d + \. \d + s $ /
905+ const timestampPattern = / \d { 4 } - \d { 2 } - \d { 2 } T /
906+
907+ // Helper function to avoid repeated string concatenation
908+ const fromBytesAbbr = val => isDef ( val ) ? ow . format . fromBytesAbbreviation ( val + "B" ) : __
909+
882910 let _procLine = _event => {
883911 try {
884- let regexes = [
885- // JDK 8 Allocation Failure (adjusted to handle multiline events)
886- / ( [ ^ ] + ) ( \d + \. \d + ) : \[ ( G C ) \( ( .* ?) \) ( .+ ?) \[ P S Y o u n g G e n : ( \d + K ) - > ( \d + K ) \( ( .* ?) \) \] ( \d + K ) - > ( \d + K ) \( ( .* ?) \) , ( \d + \. \d + ) s e c s \] \[ T i m e s : u s e r = ( \d + \. \d + ) s y s = ( \d + \. \d + ) , r e a l = ( \d + \. \d + ) s e c s \] / s,
887- // JDK 8 style regexes
888- / ( [ ^ ] + ) ( \d + \. \d + ) : \[ ( G C ) \( ( .* ?) \) \[ P S Y o u n g G e n : ( \d + K ) - > ( \d + K ) \( ( .* ?) \) \] ( \d + K ) - > ( \d + K ) \( ( .* ?) \) , ( \d + \. \d + ) s e c s \] / ,
889- // JDK 8 with +PrintHeapAtGC
890- / ( [ ^ ] + ) ( \d + \. \d + ) : \[ ( F u l l G C ) \( ( .* ?) \) \[ P S Y o u n g G e n : ( \d + K ) - > ( \d + K ) \( ( .* ?) \) \] \[ P a r O l d G e n : ( \d + K ) - > ( \d + K ) \( ( .* ?) \) \] ( \d + K ) - > ( \d + K ) \( ( .* ?) \) , \[ M e t a s p a c e : ( \d + K ) - > ( \d + K ) \( ( .* ?) \) \] , ( \d + \. \d + ) s e c s \] \[ T i m e s : u s e r = ( \d + \. \d + ) s y s = ( \d + \. \d + ) , r e a l = ( \d + \. \d + ) s e c s \] / ,
891- // JDK 8 with +PrintHeapAtGC and +PrintTenuringDistribution
892- / ( [ ^ ] + ) ( \d + \. \d + ) : \[ ( F u l l G C ) \( ( .* ?) \) \[ P S Y o u n g G e n : ( \d + K ) - > ( \d + K ) \( ( .* ?) \) \] \[ P a r O l d G e n : ( \d + K ) - > ( \d + K ) \( ( .* ?) \) \] ( \d + K ) - > ( \d + K ) \( ( .* ?) \) , \[ M e t a s p a c e : ( \d + K ) - > ( \d + K ) \( ( .* ?) \) \] , ( \d + \. \d + ) s e c s \] / ,
893- // JDK 8 with +PrintTenuringDistribution
894- / ( [ ^ ] + ) ( \d + \. \d + ) : \[ ( G C ) \( ( .* ?) \) \[ P S Y o u n g G e n : ( \d + K ) - > ( \d + K ) \( ( .* ?) \) \] ( \d + K ) - > ( \d + K ) \( ( .* ?) \) , ( \d + \. \d + ) s e c s \] \[ T i m e s : u s e r = ( \d + \. \d + ) s y s = ( \d + \. \d + ) , r e a l = ( \d + \. \d + ) s e c s \] / ,
895- // JDK 9+ style regexes
896- / ^ \[ ( .+ ) \] \s + G C \( ( \d + ) \) \s * ( .* ?) \s * ( \d + [ G M K ] ) - > ( \d + [ G M K ] ) \( ( \d + [ G M K ] ) \) \s * ( \d + \. \d + ) m s / ,
897- / ^ \[ ( .+ ) \] \s + G C \( ( \d + ) \) \s * ( .* ?) \s * M e t a s p a c e : \s * ( \d + [ G M K ] ) \( ( \d + [ G M K ] ) \) - > ( \d + [ G M K ] ) \( ( \d + [ G M K ] ) \) \s * N o n C l a s s : \s * ( \d + [ G M K ] ) \( ( \d + [ G M K ] ) \) - > ( \d + [ G M K ] ) \( ( \d + [ G M K ] ) \) \s * C l a s s : \s * ( \d + [ G M K ] ) \( ( \d + [ G M K ] ) \) - > ( \d + [ G M K ] ) \( ( \d + [ G M K ] ) \) / ,
898- // JDK 9+ Allocation Failure
899- / ^ \[ ( .+ ) \] \s + G C \( ( \d + ) \) \s * ( A l l o c a t i o n F a i l u r e ) \s * ( .* ?) \s + ( \d + [ K M G T ] ) - > ( \d + [ K M G T ] ) \( ( \d + [ K M G T ] ) \) \s + ( \d + \. \d + ) m s / ,
900- ]
901912
902913 for ( let index = 0 ; index < regexes . length ; index ++ ) {
903- let regex = regexes [ index ]
904- let match = _event . match ( regex )
914+ let match = _event . match ( regexes [ index ] )
905915 if ( match ) {
906916 let result = { }
907917
908- if ( _event . startsWith ( '[' ) ) {
918+ if ( _event . charCodeAt ( 0 ) === 91 ) { // '[' char - faster than startsWith
909919 // JDK 9+ style parsing
910- //result.index = index
911920 var heads = match [ 1 ] . split ( "][" )
912- heads . forEach ( head => {
913- if ( head . match ( / ^ \d + \. \d + s $ / ) ) {
914- result . sinceStart = parseFloat ( head . replace ( / s $ / , "" ) )
915- } else if ( head . match ( / \d { 4 } - \d { 2 } - \d { 2 } T / ) ) {
921+ for ( let i = 0 ; i < heads . length ; i ++ ) {
922+ let head = heads [ i ]
923+ if ( timePattern . test ( head ) ) {
924+ result . sinceStart = parseFloat ( head . slice ( 0 , - 1 ) ) // faster than replace
925+ } else if ( timestampPattern . test ( head ) ) {
916926 result . timestamp = ow . format . toDate ( head , "yyyy-MM-dd'T'HH:mm:ss.SSSZ" )
917927 }
918- } )
928+ }
919929 result . gcId = parseInt ( match [ 2 ] )
920- result . gcType = match [ 3 ] . trim ( )
921- if ( result . gcType == "" ) result . gcType = "none"
930+ result . gcType = match [ 3 ] . trim ( ) || "none"
922931 result . durationSecs = parseFloat ( match [ match . length - 1 ] ) / 1000 // convert ms to secs
923932
924933 if ( index === 5 ) {
925934 // Match for GC pause with heap info
926- result . heapBeforeGC = ow . format . fromBytesAbbreviation ( match [ 4 ] + "B" )
927- result . heapAfterGC = ow . format . fromBytesAbbreviation ( match [ 5 ] + "B" )
928- result . heapTotal = ow . format . fromBytesAbbreviation ( match [ 6 ] + "B" )
935+ result . heapBeforeGC = fromBytesAbbr ( match [ 4 ] )
936+ result . heapAfterGC = fromBytesAbbr ( match [ 5 ] )
937+ result . heapTotal = fromBytesAbbr ( match [ 6 ] )
929938 } else if ( index > 5 ) {
930939 if ( index == 6 ) {
931- result . metaUsedBeforeGC = ow . format . fromBytesAbbreviation ( match [ 4 ] + "B" )
932- result . metaTotalBeforeGC = ow . format . fromBytesAbbreviation ( match [ 5 ] + "B" )
933- result . metaUsedAfterGC = ow . format . fromBytesAbbreviation ( match [ 6 ] + "B" )
934- result . metaTotalAfterGC = ow . format . fromBytesAbbreviation ( match [ 7 ] + "B" )
935- result . nonClassUsedBeforeGC = ow . format . fromBytesAbbreviation ( match [ 8 ] + "B" )
936- result . nonClassTotalBeforeGC = ow . format . fromBytesAbbreviation ( match [ 9 ] + "B" )
937- result . nonClassUsedAfterGC = ow . format . fromBytesAbbreviation ( match [ 10 ] + "B" )
938- result . nonClassTotalAfterGC = ow . format . fromBytesAbbreviation ( match [ 11 ] + "B" )
939- result . classUsedBeforeGC = ow . format . fromBytesAbbreviation ( match [ 12 ] + "B" )
940- result . classTotalBeforeGC = ow . format . fromBytesAbbreviation ( match [ 13 ] + "B" )
941- result . classUsedAfterGC = ow . format . fromBytesAbbreviation ( match [ 14 ] + "B" )
942- result . classTotalAfterGC = ow . format . fromBytesAbbreviation ( match [ 15 ] + "B" )
940+ result . metaUsedBeforeGC = fromBytesAbbr ( match [ 4 ] )
941+ result . metaTotalBeforeGC = fromBytesAbbr ( match [ 5 ] )
942+ result . metaUsedAfterGC = fromBytesAbbr ( match [ 6 ] )
943+ result . metaTotalAfterGC = fromBytesAbbr ( match [ 7 ] )
944+ result . nonClassUsedBeforeGC = fromBytesAbbr ( match [ 8 ] )
945+ result . nonClassTotalBeforeGC = fromBytesAbbr ( match [ 9 ] )
946+ result . nonClassUsedAfterGC = fromBytesAbbr ( match [ 10 ] )
947+ result . nonClassTotalAfterGC = fromBytesAbbr ( match [ 11 ] )
948+ result . classUsedBeforeGC = fromBytesAbbr ( match [ 12 ] )
949+ result . classTotalBeforeGC = fromBytesAbbr ( match [ 13 ] )
950+ result . classUsedAfterGC = fromBytesAbbr ( match [ 14 ] )
951+ result . classTotalAfterGC = fromBytesAbbr ( match [ 15 ] )
943952 } else {
944- result . heapBeforeGC = ow . format . fromBytesAbbreviation ( match [ 4 ] + "B" )
945- result . heapAfterGC = ow . format . fromBytesAbbreviation ( match [ 5 ] + "B" )
946- result . heapTotal = ow . format . fromBytesAbbreviation ( match [ 6 ] + "B" )
953+ result . heapBeforeGC = fromBytesAbbr ( match [ 4 ] )
954+ result . heapAfterGC = fromBytesAbbr ( match [ 5 ] )
955+ result . heapTotal = fromBytesAbbr ( match [ 6 ] )
947956 }
948957 }
949958 } else {
950959 // JDK 8 style parsing
951- //result.index = index
952- result . timestamp = ow . format . toDate ( match [ 1 ] , "yyyy-MM-dd'T'HH:mm:ss.SSSZ" )
953- result . sinceStart = parseFloat ( match [ 2 ] )
954- result . gcType = match [ 3 ] + " " + match [ 4 ]
955-
956- //print(index)
957- //cprint(match)
958- if ( index <= 4 ) {
959- let idx = 5
960- result . PSYoungGenBeforeGC = ow . format . fromBytesAbbreviation ( match [ idx ++ ] + "B" )
961- result . PSYoungGenAfterGC = ow . format . fromBytesAbbreviation ( match [ idx ++ ] + "B" )
962- result . PSYoungGenTotal = ow . format . fromBytesAbbreviation ( match [ idx ++ ] + "B" )
963-
964- if ( index == 2 || index == 3 ) {
965- result . ParOldGenBeforeGC = ow . format . fromBytesAbbreviation ( match [ idx ++ ] + "B" )
966- result . ParOldGenAfterGC = ow . format . fromBytesAbbreviation ( match [ idx ++ ] + "B" )
967- result . ParOldGenTotal = ow . format . fromBytesAbbreviation ( match [ idx ++ ] + "B" )
968- }
960+ if ( index == 5 ) {
961+ // JDK 8 Generic GC logs (simple format)
962+ result . sinceStart = parseFloat ( match [ 1 ] )
963+ result . gcType = match [ 2 ] + " " + match [ 3 ]
964+ result . heapBeforeGC = fromBytesAbbr ( match [ 4 ] )
965+ result . heapAfterGC = fromBytesAbbr ( match [ 5 ] )
966+ result . heapTotal = fromBytesAbbr ( match [ 6 ] )
967+ result . durationSecs = parseFloat ( match [ 7 ] )
968+ } else {
969+ result . timestamp = ow . format . toDate ( match [ 1 ] , "yyyy-MM-dd'T'HH:mm:ss.SSSZ" )
970+ result . sinceStart = parseFloat ( match [ 2 ] )
971+ result . gcType = match [ 3 ] + " " + match [ 4 ]
972+
973+ if ( index <= 4 ) {
974+ let idx = 5
975+ result . PSYoungGenBeforeGC = fromBytesAbbr ( match [ idx ++ ] )
976+ result . PSYoungGenAfterGC = fromBytesAbbr ( match [ idx ++ ] )
977+ result . PSYoungGenTotal = fromBytesAbbr ( match [ idx ++ ] )
978+
979+ if ( index == 2 || index == 3 ) {
980+ result . ParOldGenBeforeGC = fromBytesAbbr ( match [ idx ++ ] )
981+ result . ParOldGenAfterGC = fromBytesAbbr ( match [ idx ++ ] )
982+ result . ParOldGenTotal = fromBytesAbbr ( match [ idx ++ ] )
983+ }
969984
970- result . heapBeforeGC = ow . format . fromBytesAbbreviation ( match [ idx ++ ] + "B" )
971- result . heapAfterGC = ow . format . fromBytesAbbreviation ( match [ idx ++ ] + "B" )
972- result . heapTotal = ow . format . fromBytesAbbreviation ( match [ idx ++ ] + "B" )
985+ result . heapBeforeGC = fromBytesAbbr ( match [ idx ++ ] )
986+ result . heapAfterGC = fromBytesAbbr ( match [ idx ++ ] )
987+ result . heapTotal = fromBytesAbbr ( match [ idx ++ ] )
973988
974- if ( index == 2 || index == 3 ) {
975- result . metaBeforeGC = ow . format . fromBytesAbbreviation ( match [ idx ++ ] + "B" )
976- result . metaAfterGC = ow . format . fromBytesAbbreviation ( match [ idx ++ ] + "B" )
977- result . metaTotal = ow . format . fromBytesAbbreviation ( match [ idx ++ ] + "B" )
978- }
989+ if ( index == 2 || index == 3 ) {
990+ result . metaBeforeGC = fromBytesAbbr ( match [ idx ++ ] )
991+ result . metaAfterGC = fromBytesAbbr ( match [ idx ++ ] )
992+ result . metaTotal = fromBytesAbbr ( match [ idx ++ ] )
993+ }
979994
980- result . durationSecs = parseFloat ( match [ idx ++ ] )
995+ result . durationSecs = parseFloat ( match [ idx ++ ] )
981996
982- if ( index == 0 || index == 2 || index == 4 ) {
983- result . userTime = parseFloat ( match [ idx ++ ] )
984- result . sysTime = parseFloat ( match [ idx ++ ] )
985- result . realTime = parseFloat ( match [ idx ++ ] )
997+ if ( index == 0 || index == 2 || index == 4 ) {
998+ result . userTime = parseFloat ( match [ idx ++ ] )
999+ result . sysTime = parseFloat ( match [ idx ++ ] )
1000+ result . realTime = parseFloat ( match [ idx ++ ] )
1001+ }
9861002 }
9871003 }
9881004 }
@@ -998,34 +1014,48 @@ var _inputFns = new Map([
9981014 _showTmpMsg ( )
9991015 if ( isString ( _res ) ) {
10001016 let lines = _res . split ( "\n" )
1001- let gcStartPattern = / ^ ( \[ \d + | \d { 4 } - \d { 2 } - \d { 2 } T ) / // Matches lines starting with '[\d+' or a timestamp
1017+ let gcStartPattern = / ^ ( \[ ? \d + | \d { 4 } - \d { 2 } - \d { 2 } T ) / // Matches lines starting with '[\d+' or a timestamp
10021018
10031019 let gcEvents = [ ]
1004- let currentEvent = [ ]
1020+ let currentEvent = ""
1021+ let hasCurrentEvent = false
10051022
1006- for ( let line of lines ) {
1023+ for ( let i = 0 ; i < lines . length ; i ++ ) {
1024+ let line = lines [ i ]
10071025 if ( gcStartPattern . test ( line ) ) {
10081026 // New GC event detected
1009- if ( currentEvent . length > 0 ) {
1010- gcEvents . push ( currentEvent . join ( "\n" ) )
1027+ if ( hasCurrentEvent ) {
1028+ gcEvents . push ( currentEvent )
10111029 }
1012- currentEvent = [ line ]
1030+ currentEvent = line
1031+ hasCurrentEvent = true
10131032 } else {
10141033 // Continuation of the current GC event
1015- currentEvent . push ( line )
1034+ if ( hasCurrentEvent ) {
1035+ currentEvent += "\n" + line
1036+ }
10161037 }
10171038 }
10181039 // Add the last GC event
1019- if ( currentEvent . length > 0 ) {
1020- gcEvents . push ( currentEvent . join ( "\n" ) )
1040+ if ( hasCurrentEvent ) {
1041+ gcEvents . push ( currentEvent )
10211042 }
10221043
1023- let results = gcEvents . map ( _procLine ) . filter ( r => isMap ( r ) )
1044+ // Process events and filter valid results in one pass
1045+ let results = [ ]
1046+ for ( let i = 0 ; i < gcEvents . length ; i ++ ) {
1047+ let result = _procLine ( gcEvents [ i ] )
1048+ if ( isMap ( result ) ) {
1049+ results . push ( result )
1050+ }
1051+ }
10241052
10251053 if ( params . javagcjoin ) {
10261054 _$o ( results , options , true )
10271055 } else {
1028- results . forEach ( result => _$o ( result , options , true ) )
1056+ for ( let i = 0 ; i < results . length ; i ++ ) {
1057+ _$o ( results [ i ] , options , true )
1058+ }
10291059 }
10301060 } else {
10311061 _exit ( - 1 , "javagc is only supported with a string input." )
@@ -1410,4 +1440,4 @@ var _inputFns = new Map([
14101440 _showTmpMsg ( )
14111441 _$o ( jsonParse ( _res , __ , __ , isString ( _res ) ) , options )
14121442 } ]
1413- ] )
1443+ ] )
0 commit comments