Jak szybki jest grep? -> grep vs awk, python, rugby, java, perl, C - przeszukiwanie logów - część 3.



Nadal grep prowadzi peleton. Trzecia próba z wykorzystaniem również funkcji systemowej, tym razem szukam jednego znaku i dopiero w kolejnych krokach przeprowadzam dalsze porównania. Warto nadmienić, że grep również korzysta z funkcji systemowych, zarówno do operacji wyszukiwania, jak i interpretacji wyrażeń regularnych.
memchr()
//
// Copyright (c) 2016 Rafal Jackiewicz
//
#define _GNU_SOURCE
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#include <string.h>
#define TRUE  1
#define FALSE 0
#define Dneedle_max 6
#define Dneedle_max_minusone Dneedle_max-1
#define Dnew_line 10
int
main(int argc, char *argv[])
{
    int             fd;
    size_t          len_max;
    char           *fileinmemory;
    struct stat     fd_st;
    char            needle[Dneedle_max];
    int             madret;
    if (argc < 3) {
    fprintf(stderr,
        "Za mamlo danych (nazwa pliku i 6 szukanych znakow).\n",
        argv[0]);
    return 1;
    }
    fd = open(argv[2], O_RDONLY);
    if (fd == -1) {
    perror("Onlyfind: open.");
    return 1;
    }
    if (fstat(fd, &fd_st) == -1) {
    perror("Onlyfind: fstat.");
    return 1;
    }
    if (!S_ISREG(fd_st.st_mode)) {
    fprintf(stderr, "%sOnlyfind: to nie plik.\n", argv[2]);
    return 1;
    }
    len_max = fd_st.st_size;
    // POPSIX API
    fileinmemory =
    mmap(0, len_max, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, fd, 0);
    if (fileinmemory == MAP_FAILED) {
    perror("Onlyfind: nmap.");
    return 1;
    }
    madret = madvise(fileinmemory, 0, MADV_WILLNEED);
    if (madret < 0) {
    perror("Onlyfind: madvise.");
    }
    if (close(fd) == -1) {
    perror("Onlyfind: close.");
    return 1;
    }
    if (strlen(argv[1]) != Dneedle_max) {
    fprintf(stderr, "%sZla dlugośc needle.\n", argv[1]);
    return 1;
    else {
    strcpy(needle, argv[1]);
    }
    char           *endfileinmemory =
    fileinmemory + len_max - Dneedle_max + 1;
    char           *mark = fileinmemory;
    char           *copymarkstart,
                   *copymarkstop;
    char           *needle_maxminus = needle + Dneedle_max_minusone;
    char           *needle_plus = needle + 1;
    size_t          needle_max_minustwo = Dneedle_max - 2;
    size_t          copylen_max = len_max;
    while ((mark = memchr(mark, *needle, copylen_max))
       && (mark < endfileinmemory)) {
    if (mark[Dneedle_max_minusone] == *needle_maxminus) {
        if (memcmp(++mark, needle_plus, needle_max_minustwo) == 0) {
        copymarkstart = mark;
        while (*(--copymarkstart) != (char) Dnew_line);
        copymarkstop = mark + Dneedle_max;
        while (*(++copymarkstop) != (char) Dnew_line);
        mark = copymarkstop;
        printf("%-.*s", copymarkstop - copymarkstart,
               copymarkstart + 1);
        copylen_max = endfileinmemory - mark;
        else {
        --copylen_max;
        }
    else {
        ++mark;
        --copylen_max;
    }
    }
    if (munmap(fileinmemory, fd_st.st_size) == -1) {
    perror("Onlyfind: munmap.");
    return 1;
    }
    return 0;

Ponownie trochę lepszy wynik, ale nadal grep jest niedościgniony. Optymalizować powyższe programy, pisać grep'a od nowa? Czy może zrobić coś ciekawszego? Może użyć więcej niż jeden rdzeń procesora? Do dalszych testów użyję najlepiej rokującej funkcji szukającej z trzeciego programu {memchr()}. Program będzie jednak wieloprocesorowy - będą uruchomione osobne procesy, nie wątki! Sam program bedzie składać się z dwóch części: główny program uruchamiający procesy (napisany w C++), który wywołuje kod szukający (napisany w C).
Programy będę uruchamiać z ustawionym uruchomieniem 1 procesu, a następnie 32 procesów. Przed uruchomieniem programy były kompilowane. Pliki wyjściowe z wynikami szukania kasuję (i synchronizuję bufory dyskowe), by nie wpływały na czas działania programu. Poprawność wykonania programu sprawdzam zliczając linie kodu wynikowego (wc -l).


********

Więcej informacji:
Informatyka, FreeBSD, Debian


***

Inne wpisy:



Update: 2018.07.17
Create: 2018.07.17

Brak komentarzy:

Prześlij komentarz