Is it feasible to split all commands into two parts to improve performance? The first part, which includes parameter validation and content checks (non-memory operations), could be processed in the I/O thread, while the second part involving concurrency-sensitive operations would be handled in the main thread.

example(And maybe can split setGenericCommand?):

void setCommand(client *c) {
    robj *expire = NULL;
    int unit = UNIT_SECONDS;
    int flags = OBJ_NO_FLAGS;
========================= proc in iothread ===============================
    if (parseExtendedStringArgumentsOrReply(c,&flags,&unit,&expire,COMMAND_SET) != C_OK) {
        return;
    }

    c->argv[2] = tryObjectEncoding(c->argv[2]);
========================= proc in iothread ===============================
    setGenericCommand(c,flags,c->argv[1],&(c->argv[2]),expire,unit,NULL,NULL);
}