Skip to content

High CPU overhead on LettuceArgSplitter #13720

@123liuziming

Description

@123liuziming

Describe the bug

Image

package com.alibaba;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public final class A {
    public static void main(String[] args) {
        long stime = System.nanoTime();
        for (int i = 0; i < 100; ++i) {
            System.out.println(splitArgs("key<XGJT:FLIGHT_DEMAND_FLOWDETAILFD_SUB113759198792552> 1800 value<WATDjUiAPb1rz8gj9oGQLcBBAGkhT4NYNj9CiA6UMuBlInORGXMWATDjUiAPb1rz8gj9oGQLcBBAGkhT4NYNj9CiA6UMuBlInORGXMWATDjUiAPb1rz8gj9oGQLcBBAGkhT4NYNj9CiA6UMuBlInORGXMWATDjUiAPb1rz8gj9oGQLcBBAGkhT4NYNj9CiA6UMuBlInORGXMWATDjUiAPb1rz8gj9oGQLcBBAGkhT4NYNj9CiA6UMuBlInORGXMWATDjUiAPb1rz8gj9oGQLcBBAGkhT4NYNj9CiA6UMuBlInORGXMWATDjUiAPb1rz8gj9oGQLcBBAGkhT4NYNj9CiA6UMuBlInORGXMWATDjUiAPb1rz8gj9oGQLcBBAGkhT4NYNj9CiA6UMuBlInORGXMWATDjUiAPb1rz8gj9oGQLcBBAGkhT4NYNj9CiA6UMuBlInORGXMWATDjUiAPb1rz8gj9oGQLcBBAGkhT4NYNj9CiA6UMuBlInORGXMWATDjUiAPb1rz8gj9oGQLcBBAGkhT4NYNj9CiA6UMuBlInORGXMWATDjUiAPb1rz8gj9oGQLcBBAGkhT4NYNj9CiA6UMuBlInORGXMWATDjUiAPb1rz8gj9oGQLcBBAGkhT4NYNj9CiA6UMuBlInORGXMWATDjUiAPb1rz8gj9oGQLcBBAGkhT4NYNj9CiA6UMuBlInORGXMWATDjUiAPb1rz8gj9oGQLcBBAGkhT4NYNj9CiA6UMuBlInORGXMWATDjUiAPb1rz8gj9oGQLcBBAGkhT4NYNj9CiA6UMuBlInORGXMWATDjUiAPb1rz8gj9oGQLcBBAGkhT4NYNj9CiA6UMuBlInORGXMWATDjUiAPb1rz8gj9oGQLcBBAGkhT4NYNj9CiA6UMuBlInORGXMWATDjUiAPb1rz8gj9oGQLcBBAGkhT4NYNj9CiA6UMuBlInORGXMWATDjUiAPb1rz8gj9oGQLcBBAGkhT4NYNj9CiA6UMuBlInORGXMWATDjUiAPb1rz8gj9oGQLcBBAGkhT4NYNj9CiA6UMuBlInORGXMWATDjUiAPb1rz8gj9oGQLcBBAGkhT4NYNj9CiA6UMuBlInORGXMWATDjUiAPb1rz8gj9oGQLcBBAGkhT4NYNj9CiA6UMuBlInORGXMWATDjUiAPb1rz8gj9oGQLcBBAGkhT4NYNj9CiA6UMuBlInORGXMWATDjUiAPb1rz8gj9oGQLcBBAGkhT4NYNj9CiA6UMuBlInORGXMWATDjUiAPb1rz8gj9oGQLcBBAGkhT4NYNj9CiA6UMuBlInORGXMWATDjUiAPb1rz8gj9oGQLcBBAGkhT4NYNj9CiA6UMuBlInORGXMWATD{jUiAPb1rz8gj9oGQL}cBBAGkhT4NYNj9CiA6UMuBlInORGXMWATDjUiAPb1rz8gj9oGQLcBBAGkhT4NYNj9CiA6UMuB{l}InORGXM>"));
        }
        long etime = System.nanoTime();
        System.out.printf("Executing split args for %d ns.", (etime - stime));
    }
}

We can use the sample above to do a simple benchmark, if we add an additional > character in the args, for example:

package com.alibaba;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public final class A {
    public static void main(String[] args) {
        long stime = System.nanoTime();
        for (int i = 0; i < 100; ++i) {
            System.out.println(splitArgs("key<XGJT:FLIGHT_DEMAND_FLOWDETAILFD_SUB113759198792552> 1800 value<WATDjUiAPb1rz8gj9oGQLcBBAGkhT4NYNj9CiA6UMuBl>InORGXMWATDjUiAPb1rz8gj9oGQLcBBAGkhT4NYNj9CiA6UMuBlInORGXMWATDjUiAPb1rz8gj9oGQLcBBAGkhT4NYNj9CiA6UMuBlInORGXMWATDjUiAPb1rz8gj9oGQLcBBAGkhT4NYNj9CiA6UMuBlInORGXMWATDjUiAPb1rz8gj9oGQLcBBAGkhT4NYNj9CiA6UMuBlInORGXMWATDjUiAPb1rz8gj9oGQLcBBAGkhT4NYNj9CiA6UMuBlInORGXMWATDjUiAPb1rz8gj9oGQLcBBAGkhT4NYNj9CiA6UMuBlInORGXMWATDjUiAPb1rz8gj9oGQLcBBAGkhT4NYNj9CiA6UMuBlInORGXMWATDjUiAPb1rz8gj9oGQLcBBAGkhT4NYNj9CiA6UMuBlInORGXMWATDjUiAPb1rz8gj9oGQLcBBAGkhT4NYNj9CiA6UMuBlInORGXMWATDjUiAPb1rz8gj9oGQLcBBAGkhT4NYNj9CiA6UMuBlInORGXMWATDjUiAPb1rz8gj9oGQLcBBAGkhT4NYNj9CiA6UMuBlInORGXMWATDjUiAPb1rz8gj9oGQLcBBAGkhT4NYNj9CiA6UMuBlInORGXMWATDjUiAPb1rz8gj9oGQLcBBAGkhT4NYNj9CiA6UMuBlInORGXMWATDjUiAPb1rz8gj9oGQLcBBAGkhT4NYNj9CiA6UMuBlInORGXMWATDjUiAPb1rz8gj9oGQLcBBAGkhT4NYNj9CiA6UMuBlInORGXMWATDjUiAPb1rz8gj9oGQLcBBAGkhT4NYNj9CiA6UMuBlInORGXMWATDjUiAPb1rz8gj9oGQLcBBAGkhT4NYNj9CiA6UMuBlInORGXMWATDjUiAPb1rz8gj9oGQLcBBAGkhT4NYNj9CiA6UMuBlInORGXMWATDjUiAPb1rz8gj9oGQLcBBAGkhT4NYNj9CiA6UMuBlInORGXMWATDjUiAPb1rz8gj9oGQLcBBAGkhT4NYNj9CiA6UMuBlInORGXMWATDjUiAPb1rz8gj9oGQLcBBAGkhT4NYNj9CiA6UMuBlInORGXMWATDjUiAPb1rz8gj9oGQLcBBAGkhT4NYNj9CiA6UMuBlInORGXMWATDjUiAPb1rz8gj9oGQLcBBAGkhT4NYNj9CiA6UMuBlInORGXMWATDjUiAPb1rz8gj9oGQLcBBAGkhT4NYNj9CiA6UMuBlInORGXMWATDjUiAPb1rz8gj9oGQLcBBAGkhT4NYNj9CiA6UMuBlInORGXMWATDjUiAPb1rz8gj9oGQLcBBAGkhT4NYNj9CiA6UMuBlInORGXMWATD{jUiAPb1rz8gj9oGQL}cBBAGkhT4NYNj9CiA6UMuBlInORGXMWATDjUiAPb1rz8gj9oGQLcBBAGkhT4NYNj9CiA6UMuB{l}InORGXM>"));
        }
        long etime = System.nanoTime();
        System.out.printf("Executing split args for %d ns.", (etime - stime));
    }
}

Due to the mismatch of < and >, the performance of regex is significantly degraded due to backtracking.

Steps to reproduce

JFR file:

lettuce-1744556713-arms.jfr.zip

Expected behavior

Normal CPU overhead while splitting args.

Actual behavior

High CPU overhead while splitting args.

Javaagent or library instrumentation version

main

Environment

JDK:
OS:

Additional context

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingneeds triageNew issue that requires triage

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions