Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.97/35: Рейтинг темы: голосов - 35, средняя оценка - 4.97
1102 / 237 / 21
Регистрация: 20.05.2016
Сообщений: 1,068
Записей в блоге: 21
1

Скорость чтения csv с разных носителей

21.05.2020, 23:27. Показов 6368. Ответов 148
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Добрый день, джентльмены.
На днях набросал простой код поиска нужной строки в CSV-файле, см. под спойлером
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
extern "C" __declspec(dllexport) LPXLOPER12  WINAPI FindInCSV(char *  arg1, char *  arg2, wchar_t *  arg3)
{
    LPXLOPER12 OperOut = new XLOPER12;
    OperOut->xltype = xltypeStr | xlbitDLLFree;
    OperOut->val.str = new XCHAR[32767 + 2]; //+1 под размер + 1 под нуль-терминатор
    OperOut->val.str[0] = 0;
    OperOut->val.str[1] = '\0';
    std::filebuf fb;
    if (fb.open(arg1, std::ios::in | std::ios::binary))
    {
        int x = 0;
        int lenStrOut = 0; //0й элемент - размер строки
        int lenArg3 = wcslen(arg3);
        bool overflow = false;
        std::string str;
        std::istream is(&fb);
        XCHAR* strTmp= OperOut->val.str + 1;
 
        while (is) 
        {
            std::getline(is, str);
            size_t found = str.find(arg2);
            if (found != std::string::npos)
            {
                x++;
                if (lenArg3 > 0 && x > 1)
                {
                    if (lenStrOut + lenArg3 > 32767) { overflow = true;  goto end_; }
                    wcscpy(strTmp + lenStrOut, arg3);
                    lenStrOut = lenStrOut + lenArg3;
 
                    if (lenStrOut + str.length() > 32767) { overflow = true;  goto end_; }
                    MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, str.c_str(), -1, strTmp + lenStrOut, str.length() + 1);
                    lenStrOut = lenStrOut + str.length();
                }
                else if (lenArg3 > 0)
                {
                    if (lenStrOut + str.length() > 32767) { overflow = true;  goto end_; }
                    MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, str.c_str(), -1, strTmp + lenStrOut, str.length() + 1);
                    lenStrOut = lenStrOut + str.length();
                }
                else
                {
                    if (lenStrOut + str.length() > 32767) { overflow = true;  goto end_; }
                    MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, str.c_str(), -1, strTmp + lenStrOut, str.length() + 1);
                    lenStrOut = lenStrOut + str.length();
                    goto end_ ;
                }
            };
        }
    end_:
        if (overflow) {
            wcscpy(strTmp, L"Qverflow. Max char 32767\0");
            OperOut->val.str[0] = 24;
        }
        else
        {
            OperOut->val.str[0] = lenStrOut;
        }
        fb.close();
    }
    return OperOut;
}

Сегодня протестировал работу на з-х накопителях:
HDD WDC WD10EACS-00ZJB0 (1000 ГБ, SATA-II)
HDD WDC WD5000AAKX-001CA0 (500 ГБ, 7200 RPM, SATA-III)
SSD KINGSTON SV300S37A120G (120 ГБ, SATA-III)

В итоге время обработки CSW-файла размером 1ГБ у всех примерно одинаковое, что стало для меня откровением. Я предполагал, что в данном коде узкое место скорость чтения с накопителя. Чем можно объяснить такой результат теста?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
21.05.2020, 23:27
Ответы с готовыми решениями:

Скорость записи и чтения данных с разных источников - из реестра и Json
Всем привет. Возникла необходимость где то хранить данные приложения. Было выбрано два варианта: ...

Создание тестов на скорость чтения и скорость записи
Проблемка такая - пишу простенький тест на скорость записи и скорость чтения, локальных и съемных...

Так ли важна в реальной жизни скорость записи SSD, или смотреть надо только на скорость чтения, а на запись пофигу
https://www.citilink.ru/catalog/computers_and_notebooks/hdd/ssd_in/420250/ вот у него скорость...

Программа для чтения csv
Нужно прочитать csv-файл, записать в массив и потом делать с ним всякие манипуляции и сортировки...

148
18840 / 9839 / 2408
Регистрация: 30.01.2014
Сообщений: 17,280
21.05.2020, 23:38 2
Цитата Сообщение от bedvit Посмотреть сообщение
Чем можно объяснить такой результат теста?
Тем, что вы в своем коде не вырабатываете ресурс указанных устройств. Т.е. ваш код не создает достаточную для проявления разницы нагрузку.
0
1102 / 237 / 21
Регистрация: 20.05.2016
Сообщений: 1,068
Записей в блоге: 21
22.05.2020, 00:37  [ТС] 3
DrOffset, тогда где в коде узкое место, ведь его скорость во что-то упирается. Выполняется он 9 секунд на 1ГБ.

Добавлено через 1 минуту
ЦП тоже не загружен. ОЗУ? Тоже нет.
0
18840 / 9839 / 2408
Регистрация: 30.01.2014
Сообщений: 17,280
22.05.2020, 01:11 4
Цитата Сообщение от bedvit Посмотреть сообщение
ведь его скорость во что-то упирается.
Скорость упирается в ваш алгоритм, видимо.

Добавлено через 2 минуты
C++
1
2
3
        while (is) 
        {
            std::getline(is, str);
Вот тут вы читаете построчно. Каждый цикл - одна строка. Очевидно, что это достаточно медленно само по себе.

Читайте сразу большими блоками, например по 16 мегабайт за раз, и скорость должна вырасти.
0
1102 / 237 / 21
Регистрация: 20.05.2016
Сообщений: 1,068
Записей в блоге: 21
22.05.2020, 10:48  [ТС] 5
Про блоки, можно подумать. Здесь к размышлению, то, что строка может быть и первой и последней и файл может быть 1 МБ и 10 ГБ. Еще по 16 мегабайт, нужно сшивать строки на границах, т.к. строк не ровное кол-во влезает и т.д.
Мне, как непосвященному в тонкости низкоуровнего железа, остается непонятен следующий момент: пусть я читаю построчно, пусть скорость чтения блоками будет быстрее, но почему на разных дисках одинаковое время выполнения (думаю и с блоками будет похожая ситуация?) Куда я упираюсь при чтении строками, память, кеш, ЦП на порядки быстрее работают, где очередь? почему SSD мне дает такую же скорость как HDD?
0
Заблокирован
22.05.2020, 10:58 6
Цитата Сообщение от bedvit Посмотреть сообщение
Куда я упираюсь при чтении строками, память, кеш, ЦП на порядки быстрее работают, где очередь? почему SSD мне дает такую же скорость как HDD?
Кликните здесь для просмотра всего текста
Тебе ж сказали - чтение с любого из этих носителей в разы быстрее обработки считанной инфы твоим кривым алгоритмом.

Попробуй просто прочитать файл построчно, без обработки, и померить время.
0
nd2
3437 / 2816 / 1249
Регистрация: 29.01.2016
Сообщений: 9,426
22.05.2020, 11:37 7
Цитата Сообщение от bedvit Посмотреть сообщение
Про блоки, можно подумать.
Используй Си-шные функции чтения, быстрее работают. Надеюсь, Release пробуешь?
0
1102 / 237 / 21
Регистрация: 20.05.2016
Сообщений: 1,068
Записей в блоге: 21
22.05.2020, 12:01  [ТС] 8
Verevkin, протестирую, отпишусь. nd2, да, пока не настолько стар. Вы имеете ввиду getline, не std-ю?
0
nd2
3437 / 2816 / 1249
Регистрация: 29.01.2016
Сообщений: 9,426
22.05.2020, 12:12 9
Цитата Сообщение от bedvit Посмотреть сообщение
имеете ввиду getline
Да, и прочие fstream-ы.

Добавлено через 8 минут
Сравнить содержимое файлов между собой, и если оно совпадает, то вывести на экран имена этих файлов
1
1102 / 237 / 21
Регистрация: 20.05.2016
Сообщений: 1,068
Записей в блоге: 21
22.05.2020, 12:13  [ТС] 10
Сегодня подготовлю стенд, протестирую по внесёнными предложениям, итоги выложу.
0
nd2
3437 / 2816 / 1249
Регистрация: 29.01.2016
Сообщений: 9,426
22.05.2020, 12:26 11
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
Самое быстрое - это читать и записывать блоками (какого размера точно не понятно, но около 50000 и больше);
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
#include <iostream>
#include <string>
#include <ctime>
#include <fstream>
 
using namespace std;
 
const int N = 1000000; // количество строк в файле
const int L = 500;     // длина строки
 
void createfile() //создание файла для теста
{
    string str = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
    ofstream fout("file1.txt");
    for (int i = 0; i < N; ++i)
    {
        fout << i + 1;
        fout << str << endl;
    }
    fout.close();
}
 
int main()
{
    //createfile(); //создание файла для теста
 
    const int size = 51200;
    char* buffer = new char[size];
    //char buffer[size];
    char str1[L] = {'\0'};
    
    clock_t t1 = clock();
    FILE *fin = fopen("file1.txt", "rb"); // в бинарном быстрее
    
    if (!fin) printf("Error!\n");
    else
    {
        FILE *fout = fopen("file2.txt", "wb");
 
        // посимвольно
        /*begin...............................
         char ch;
         while (true)
         {
             ch = fgetc(fin);
             if (feof(fin))
                 break;
         }
            
        //*///end ...................................
        
        // построчно
      /*begin...............................
        
          while (fgets(str1, L, fin))
                fputs(str1, fout);
      //*///end ................................... 
 
      // блоками
     /*begin...............................
         //int n = 0;
         while (fread(buffer, size, 1, fin))
            fwrite(buffer, size, 1, fout);
             //++n;
        
     //*///end ...................................  
    
     // блоком, размером с размер файла
     /*begin...............................
        
        fseek(fin, 0, SEEK_END); 
        int size = ftell(fin);
        char * buffer = (char*) malloc(size);
        
        rewind(fin);
        fread(buffer, 1, size, fin);
        fwrite(buffer, 1, size, fout);
        free(buffer);
     
     //*///end ...................................  
        
        fclose(fout);
        fclose(fin);
        
        clock_t t2 = clock();
        printf("%f\n", (t2 - t1 + .0) / CLOCKS_PER_SEC); // время отработки
        printf("\n");
        //printf("%i", n);
    }
  
    system("pause");
    return 0;
}
0
Эксперт С++
8739 / 4317 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
22.05.2020, 16:31 12
Цитата Сообщение от bedvit Посмотреть сообщение
Чем можно объяснить такой результат теста?
Цитата Сообщение от bedvit Посмотреть сообщение
std::getline(is, str);
тормоз - тоже механизм.

ну например... под windows можно отмаппить весь файл на память,
и тогда скорость чтения вырастит во многие разы.
1
1102 / 237 / 21
Регистрация: 20.05.2016
Сообщений: 1,068
Записей в блоге: 21
22.05.2020, 23:46  [ТС] 13
Мое почтение, джентльмены.
Тестовый стенд:
Кликните здесь для просмотра всего текста
Операционная система Microsoft Windows 10 Professional
Тип ЦП QuadCore AMD Phenom II X4 Black Edition 955, 3200 MHz (16 x 200)
Системная плата Asus M4A89GTD Pro (2 PCI, 1 PCI-E x1, 1 PCI-E x4, 2 PCI-E x16, 4 DDR3 DIMM, Audio, Video, Gigabit LAN, IEEE-1394)
Чипсет системной платы AMD 890GX, AMD K10
Системная память 8192 МБ (DDR3-1333 DDR3 SDRAM)
DIMM1: Kingston 99U5474-028.A00LF 4 ГБ DDR3-1333 DDR3 SDRAM (9-9-9-24 @ 666 МГц) (8-8-8-22 @ 609 МГц) (7-7-7-20 @ 533 МГц) (6-6-6-17 @ 457 МГц)
DIMM2: Kingston 99P5458-005.A00LF 4 ГБ DDR3-1333 DDR3 SDRAM (9-9-9-24 @ 666 МГц) (8-8-8-22 @ 609 МГц) (7-7-7-20 @ 533 МГц) (6-6-6-17 @ 457 МГц)
Хранение данных
Дисковый накопитель KINGSTON SV300S37A120G (120 ГБ, SATA-III)
Дисковый накопитель WDC WD10EACS-00ZJB0 (1000 ГБ, SATA-II)

+CSV-файла размером 1ГБ (длина строки в тесте 200 символов, но может быть разная, но не более 33000 символов)
Код (Release):
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#include "stdafx.h"
#include <string>
#include <fstream>
#include <ctime>
#include <iostream>
#include <exception>
#include <stdio.h>
 
int main() 
{
    clock_t t1 = clock();
    std::ifstream is;
    std::filebuf * fb = is.rdbuf();
    fb->open("C:\\CSV_1_GB.csv", std::ios::in | std::ios::binary);
        while (is) 
        {
            std::string str;
            std::getline(is, str);
            size_t found = str.find("ASD123FGH456");
            if (found != std::string::npos) { std::cout << "Find OK: " << std::endl; };
        }
    fb->close();
    clock_t t2 = clock();
    printf("SSD KINGSTON SV300S37A120G (120 GB, SATA-III): std::getline + Find: Time - %f\n", (t2 - t1 + .0) / CLOCKS_PER_SEC); // время отработки
 
    ///////////////////////////////////////////////
    t1 = clock();
    std::ifstream is2;
    std::filebuf * fb2 = is2.rdbuf();
    fb2->open("C:\\CSV_1_GB.csv", std::ios::in | std::ios::binary);
    while (is2) 
    {
        std::string str;
        std::getline(is2, str);
    }
    fb2->close();
    t2 = clock();
    printf("SSD KINGSTON SV300S37A120G (120 GB, SATA-III): std::getline: Time - %f\n", (t2 - t1 + .0) / CLOCKS_PER_SEC); // время отработки
 
    ///////////////////////////////////////////////
    t1 = clock();
    std::ifstream is3;
    std::filebuf * fb3 = is3.rdbuf();
    fb3->open("D:\\CSV_1_GB.csv", std::ios::in | std::ios::binary);
    while (is3) 
    {
        std::string str;
        std::getline(is3, str);
    }
    fb3->close();
    t2 = clock();
    printf("HDD WDC WD10EACS-00ZJB0 (1000 GB, SATA-II): std::getline: Time - %f\n", (t2 - t1 + .0) / CLOCKS_PER_SEC); // время отработки
 
    ///////////////////////////////////////////////
#pragma warning(disable : 4996)
    t1 = clock();
    char str[33000];
    char* estr;
    FILE* file;
    file = fopen("C:\\CSV_1_GB.csv", "r");
    if (file != NULL)
    {
        while (1)
        {
            estr = fgets(str, sizeof(str), file);
            if (estr == NULL) { break; }
        }
        fclose(file);
    }
    t2 = clock();
    printf("SSD KINGSTON SV300S37A120G (120 GB, SATA-III): fgets: Time - %f\n", (t2 - t1 + .0) / CLOCKS_PER_SEC); // время отработки
 
    ///////////////////////////////////////////////
    t1 = clock();
    char str2[33000];
    char* estr2;
    FILE* file2;
    file2 = fopen("D:\\CSV_1_GB.csv", "r");
    if (file2 != NULL)
    {
        while (1)
        {
            estr2 = fgets(str, sizeof(str2), file2);
            if (estr2 == NULL) { break; }
        }
        fclose(file2);
    }
    t2 = clock();
    printf("HDD WDC WD10EACS-00ZJB0 (1000 GB, SATA-II): fgets: Time - %f\n", (t2 - t1 + .0) / CLOCKS_PER_SEC); // время отработки
    system("pause");
    return 0;
}


Результаты (запуск exe)
SSD KINGSTON SV300S37A120G (120 GB, SATA-III): std::getline + Find: Time - 18.017000
SSD KINGSTON SV300S37A120G (120 GB, SATA-III): std::getline: Time - 16.798000
HDD WDC WD10EACS-00ZJB0 (1000 GB, SATA-II): std::getline: Time - 16.791000
SSD KINGSTON SV300S37A120G (120 GB, SATA-III): fgets: Time - 9.222000
HDD WDC WD10EACS-00ZJB0 (1000 GB, SATA-II): fgets: Time - 8.974000

Выводы:
1. Поиск нужных символов (подстроки) в строке на общее время выполнение влияет мало.
2. Скорость чтения всех строк не зависит от скорости самого диска (HDD или SSD), даже с применением Си-функций
3. Си-функций работают в 2 раза быстрее std::

Опять не вырабатываем ресурс указанных устройств.
0
nd2
3437 / 2816 / 1249
Регистрация: 29.01.2016
Сообщений: 9,426
22.05.2020, 23:50 14
Цитата Сообщение от bedvit Посмотреть сообщение
C++
1
file = fopen("C:\\CSV_1_GB.csv", "r");
В бинарном нужно, будет ещё быстрее.
0
693 / 303 / 99
Регистрация: 04.07.2014
Сообщений: 846
22.05.2020, 23:54 15
Есть ещё кэш ОС. Поэтому перед тестом скорости обработки файла. Надо проработать с файлами размером больше, чем ОЗУ
0
1487 / 1414 / 240
Регистрация: 19.02.2010
Сообщений: 3,915
23.05.2020, 00:02 16
Цитата Сообщение от bedvit Посмотреть сообщение
Опять не вырабатываем ресурс указанных устройств.
Не читайте построчно.
Используйте специфические для ОСи функции чтения файла.
Т.е. под виндой - её обычный ReadFile(), но асинхронный (overlapped), чтобы получить возможность один кусок файла читать, и одновременно обрабатывать ранее прочитанный. Плюс при открытии файла через CreateFile() есть ещё флажок FILE_FLAG_NO_BUFFERING (чтобы лишний раз не кэшировать данных). Соответственно, вместо fgets() нужно будет написать свой код поиска концов строк в буфере.
1
18840 / 9839 / 2408
Регистрация: 30.01.2014
Сообщений: 17,280
23.05.2020, 00:11 17
Цитата Сообщение от bedvit Посмотреть сообщение
Опять не вырабатываем ресурс указанных устройств.
У современных накопителей есть кеш, обычно он больше 8 мегабайт. Если вы не пробуете читать больше данных за раз, то разницу никогда не увидите. Я вам не зря же выше сказал, чтобы вы делали буфер чтения не менее 16 Мб.

Цитата Сообщение от bedvit Посмотреть сообщение
Си-функций работают в 2 раза быстрее std::
В вашем тесте как минимум кардинально различается работа с памятью. В "Си" варианте вы читаете в заранее выделенную память на стеке, а в "С++" варианте память постоянно выделяется динамически. Это наверняка вносит существенный вклад в разброс производительности. Поэтому выводы на основе этого теста делать нельзя.
0
Заблокирован
23.05.2020, 00:24 18
Файл в 1 Гб вполне можно схавать с диска в память ваще целиком. Мож ты поделишься своим файлом, чтоб народ у себя поэкспериментировал? Или он аццки секретный? Я иногда таким онанизмом балуюсь, когда скучно.

0
1102 / 237 / 21
Регистрация: 20.05.2016
Сообщений: 1,068
Записей в блоге: 21
23.05.2020, 12:45  [ТС] 19
nd2, тоже так подумал, в след.тесте внесу правки.
VTsaregorodtsev, интересная информация, теперь надо нагуглить как их использовать. Я так понимаю вместе нельзя, только асинхронность или только кеширование. Понять, что будет эффективнее.
AlexVRud, есть файл на 10 ГБ., больше оперативки. Но если читать построчно, то разницы нет.
DrOffset, буфер в 16 МБ, пока не пойму что это даст. Буфер есть у накопителя, но скорость его подгрузки предполагаю зависит от скорости чтения с диска. Сам файл у меня явно больше этого кеша. Да в СИ варианте буфер на стеке, и в stl каждый раз создаем строку в куче и подозреваю ее из кучи удаляем. Предполагаю это основная причина разницы в скорости. У меня строка не может быть больше 32КБ. Не будет ли буфер в 16 МБ тратой ресурсов и времени?
Представляется, что вариант от VTsaregorodtsev, с чтением в буфер по 32 КБ, и далее с поиском разделителя строки, будет самый быстрый, мнения? Такого еще не пилил, выходит если разделитель найден, ищем следующий и так до последнего. Далее грузим в буфер другие 32КБ, начиная с места последнего разделителя? Хорошо бы примерчик глянуть аналогичный.
Verevkin, да нет ничего секретного, текст 5.2 млн строк в среднем по 200 символов. Могу накидать генератор, или можно использовать выше от nd2. Файл не всегда будет 1ГБ есть и 10. Да и смысл его весь грузить в оперативку, если нам нужна будет вторая строка?
0
Заблокирован
23.05.2020, 12:53 20
Цитата Сообщение от bedvit Посмотреть сообщение
Да и смысл его весь грузить в оперативку, если нам нужна будет вторая строка?
Дык тыж тестируешь скорость работы накопителей. Или передумал уже? Исключи анализ данных при чтении для чистоты эксперимента. Это независимая подзадача, которую можно гнать в побочном треде.
0
23.05.2020, 12:53
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
23.05.2020, 12:53
Помогаю со студенческими работами здесь

Скорость импорта CSV
Здравствуйте. Прислали мне CSV-шник размером 10 гигов, чтобы сделать пару запросов. Поставил я...

Bat - файл для чтения только одной строки из файла CSV
Добрый день! Подскажите пожалуйста как сделать батник чтобы он выводил только одну (2, 3, 4,...)...

Как правильно написать скрипт для чтения файла с расширением .csv(Excel) ?
как правильно написать скрипт для чтения файла с расширением .csv(Excel) пишу вот такой програмный...

Скорость чтения/записи
Всем привет! Есть ли какие-нибудь библиотеки в Java, чтобы узнать скорость чтения/записи на диск?...

скорость чтения - копейки
Проблема в том, что скорость чтения на жестком упала более чем в сотни раз...жесткому около...

Скорость чтения DVD
Здравствуйте форумчане, Подскажите пожалуйста, вот у современных DVD приводов скорость x16 (что...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru