:[ Помогите найти лучший вариант ]:
есть сособ записи в файл
ofstream list("C:\\файл.txt");
Я пишу прогу для создания огромных листов(до 100Mb весом) процесс записи таким образом занимает немало времени
//----------------------
#include "fstream.h"
#include "iostream.h"
ofstream list("C:\\файл.txt");
main()
{
for(int i = 0; i < 10000; i++) list << "Строчка для записи\n";
}
//----------------------
темоблее что в процессе создания листа таким способом прога может зависнуть..
Пожалуйста прошу помоч найти оптимально быстрый вариант записи в файл..
Может кто что нибуть знает?.. прошу привести примеры кодом..
А лучше используй FileOpen? FileCreate, FileWrite, FileRead
String h[5000];
String file_name = "C:\\out\\out.txt";
int iFileHandle = CreateFile(file_name);
for(int i = 0; i<5000; i++)
WriteFile(iFileHandle, h[0].c_str(), h[0].Length());
FileClose(iFileHandle);
и тот который я использывал оказался быстрее, чем предложенный.. хмм
Может кто что ещё знает?..
Я начал тестить и искать наибыстрый вариант..
и тот который я использывал оказался быстрее, чем предложенный.. хмм
Может кто что ещё знает?..
Самый простой способ заоптимайзить запись в файл - это использовать буфферизацию - тобишь сначала подготавливаешь некий буффер в памяти (разумного расмера) - заполняешь его данными - и потом его пишешь в файл - получится гораздо быстрее.
Короткий пример:
#include <stdio.h>
#define BUF_SZ 0x1000 //к примеру - главное не делать слишком большим.
void main(void)
{
int left=BUF_SZ,len,sz;
char dump[BUF_SZ],str[40],*ptr;
FILE *fp=fopen("c:\\temp\\out.txt","wb");
strcpy(str,"Строчка для записи\n");
len=strlen(str);
ptr=dump;
for(int i = 0; i < 10000; i++)
{
sz=len;
if (sz>left) sz=left;
memcpy(ptr,str,sz);
left-=sz;
if (!left)
{
fwrite(dump,BUF_SZ,1,fp);
left=BUF_SZ;
ptr=dump;
sz=len-sz;
if (sz)
{
memcpy(ptr,str+(len-sz),sz);
left-=sz;
}
}
ptr+=sz;
}
len=BUF_SZ-left;
if (len) fwrite(dump,len,1,fp);
fflush(fp);
fclose(fp);
}
Это только пример - но рабочий - я проверял.
P.S. Только что провел сравнение быстродействия.
При 10000 - скоростные характеристики одинаковые.
А вот уже при 1000000 строк появляются расхождения - 203 мс на моем способе против 812 на твоем. Так что выбирай :) Можно поэкспериментировать с размером буфера - может еще удастся подстегнуть скорость.
сейчас буду разбираться с этим ; )
в 8 раз быстрее!..
хоть код и сложен для меня.. думаю что с ним следует разобраться..
Попутно возник ещё вопрос как перепрыгнуть на следующую строку?.. '\n' не помогает
Скорость просто зверская!..
в 8 раз быстрее!..
хоть код и сложен для меня.. думаю что с ним следует разобраться..
Попутно возник ещё вопрос как перепрыгнуть на следующую строку?.. '\n' не помогает
Не совсем понял - перепрыгнуть на следующую строку? - тебе в файл надо записать с переходом строки или ты не знаешь как выделить из дампа памяти одну строку?
P.S. Кстати - сегодня у меня возникла необходимость в реализации моего-же алгоритма, правда для других целей :) По этому поводу написал класс реализующий описанный способ - ежели хочешь могу поделиться.
В том что файл открывался с отрибутами для записи в двичном виде, а не в текстовом..
поэтому '\n' несрабатывала..
А так всё терь работает..
> Подилеться..
- давай.. буду благодарен, может и я буду использывать..
150мб за 5 сек.
но вот если сторочка надписи должна меняться каждый раз, вот тогда скорость совсем опускаеться..
и почти уступает другим видам записи..
Я вот о чём:
//----------------------------------------
#include <vcl.h>
#include <iostream.h>
#include <fstream.h>
#include <stdio.h>
#include <conio.h>
void main(void)
{
#define BUF_SZ 0x1000 // размер буфера
cout << "ready!\n";
getch();
cout << "wait...\n";
int left = BUF_SZ ,len,sz;
char dump[BUF_SZ], *ptr = dump;
String str;
FILE *fp=fopen("c:\\demo.txt","w"); // Создаёт текстовый файл для запаси, а двочный это "wb"
for(int i = 1000000; i <= 9999999; i++)
{
str = IntToStr(i) + '\n'; ////// вот тут строчка меняеться каждый раз.. и это вызывает 100% уменьшение скорости
len=strlen(str.c_str());
sz=len;
if (sz>left) sz=left;
memcpy(ptr,str.c_str(),sz);
left-=sz;
if (!left)
{
fwrite(dump, BUF_SZ, 1, fp);
left=BUF_SZ;
ptr=dump;
sz=len-sz;
if (sz)
{
memcpy(ptr,str.c_str()+(len-sz),sz);
left-=sz;
}
}
ptr+=sz;
}
len=BUF_SZ-left;
if (len) fwrite(dump,len,1,fp);
fflush(fp);
fclose(fp);
cout << "[ok]";
getch();
}
//----------------------------------------
Может быть кто нибуть сможет изменить этот код чтобы запись была высокой при изменении надписи каждый раз, или может быть кто что посоветует ещё
но только в том случае если строчка не меняеться каждый раз
//--------------------
#include <vcl.h>
#include <iostream.h>
#include <conio.h>
#include <stdio.h>
void main(void)
{
cout << "ready!\n";
getch();
cout << "wait...\n";
FILE *fp = fopen("C:\\demo.txt", "w");
String str = "Line\n";
for(int i = 1000000; i <= 9999999; i ++)
fputs((str).c_str(), fp);
cout << "[ok]\a";
getch();
}
//--------------------
простой и быстрый..
но не думаю что оптимальный вариант
скажите пожалуйста..
каким образом было бы лучше получить время в мили сикундах между двумя промежутками времени?..
скажите пожалуйста..
GetTickCount()
/*** небольшое тестирование ***/
fputs():
Строка неизменна = 5500
Строка меняется = 29641
ofstream
Строка неизменна = 9828
Строка меняется = 12109
буфер 0X1000
Строка неизменна = 7265
Строка меняется = 27656
буфер 0X50
Строка неизменна = 5500
Строка меняется = 27656
/***
Вот и оптимальные варианты:
Если строка неизменна - fputs() т.к. у буфера сложна запись
Если меняется - ofstream
***/
А что если в проге испольовать асемблерные вставки?.. это же должно быть быстрее!???..
Еще можно попробовать файл писать одновременно по частям несколькими разными потоками, а затем склеить записанные части в один целый файл.