Performance comparison between recv peek and memory copy

Time:2020-9-16

Performance comparison between recv peek and memory copy

scene

Compare the program pairs per secondUnix Socketimplementpeek recvThe number of operations and the program per secondcopyMemory times.

Copy memory

withcopy 256KBFor example, the code is as follows:

#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <stdint.h>
#include <iostream>

#define BUFFER_SIZE 256 * 1024

uint64_t get_current_ms()
{
    struct timeval tv;
    gettimeofday(&tv, NULL);
    return tv.tv_sec * 1000 + tv.tv_usec / 1000;
}

int main(int argc, char const *argv[])
{
    long count = 1000000;
    uint64_t start = get_current_ms();
    uint64_t end, diff, ret;

    char *src = (char *)malloc(BUFFER_SIZE);
    char *dest = (char *)malloc(BUFFER_SIZE);

    for (size_t i = 0; i < count; i++)
    {
        memcpy(dest, src, BUFFER_SIZE);
    }

    diff = get_current_ms() - start;
    ret = count / diff * 1000;

    STD:: cout < < RET: "< RET < < times / sec < < STD:: endl;
    return 0;
}

recv peek

We simulate it in the same processSwooleClient fromUnix Socketsend outswEventData, andSwooleServer fromUnix SocketcallrecvcomepeekOutswEventDataInsideswDataHead

The code is as follows:

#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
#include <iostream>
#include <unistd.h>
#include <errno.h>

#define SW_IPC_MAX_SIZE            8192  // for IPC, dgram and message-queue max size
#define SW_IPC_BUFFER_SIZE         (SW_IPC_MAX_SIZE - sizeof(struct _swDataHead))

typedef struct _swDataHead
{
    int fd;
    uint32_t len;
    int16_t reactor_id;
    uint8_t type;
    uint8_t flags;
    uint16_t server_fd;
    uint16_t ext_info;
} swDataHead;

typedef struct
{
    swDataHead info;
    char data[SW_IPC_BUFFER_SIZE];
} swEventData;

uint64_t get_current_ms()
{
    struct timeval tv;
    gettimeofday(&tv, NULL);
    return tv.tv_sec * 1000 + tv.tv_usec / 1000;
}

int main(int argc, char const *argv[])
{
    long count = 1000000;
    int pipes[2];
    int &read_fd = pipes[0];
    int &write_fd = pipes[1];
    uint64_t start, end, diff, ret;
    swEventData send_data;
    swDataHead head;

    socketpair(AF_UNIX, SOCK_DGRAM, 0, pipes);
    send_data.info.reactor_id = 1;

    if (send(write_fd, (void *)&send_data, sizeof(send_data), 0) < 0)
    {
        std::cout << "send error: " << strerror(errno) << std::endl;
        exit(0);
    }
    sleep(1);

    start = get_current_ms();
    for (size_t i = 0; i < count; i++)
    {
        if (recv(read_fd, (void *)&head, sizeof(head), MSG_PEEK) < 0)
        {
            std::cout << "send error: " << strerror(errno) << std::endl;
            exit(0);
        }
    }

    diff = get_current_ms() - start;
    ret = count / diff * 1000;

    STD:: cout < < RET: "< RET < < times / sec < < STD:: endl;

    return 0;
}

Pressure test results

During the actual test, the compiler turns onO2There is no significant difference between the optimization results and the optimization results

copy

Memory size rate
8KB 4950000 times / S
64KB 620000 times / S
128KB 283000 times / S
256KB 129000 times / sec

peek

rate
2793000 times / S