QTemporaryFile takes forever
-
So, you want to store each object in its own file?
And you have "very big number of objects", right?
Then you will create a very big number of temporary files, I don't think such an approach will deliver a good performance. -
That's not exactly the point, if I simulate the same behaviour using QFile the results is MUCH faster and creating the file does not depend on the number of files already in the folder
QList<QFile*> allfiles; QTime timeCounter; QString tempFileName; QFile file("C:/Temp/ChangeAverageTime.txt"); file.open(QIODevice::WriteOnly | QIODevice::Text); QTextStream stream(&file); timeCounter.start(); for (int i = 0; i < 2000; ++i) { if (i % 100 == 0) { stream << QString("%1 Files. Time: %2").arg(i).arg(static_cast<double>(timeCounter.restart()) / 1000.0, 0, 'f', 2) << '\n'; } tempFileName.clear(); do { // Generate random file name for (int j = 0; j < 15; ++j) { tempFileName.append(static_cast<char>(97 + (qrand() % 26))); } } while (QFile::exists("C:/temp/TempTest/" + tempFileName)); allfiles.append(new QFile("C:/temp/TempTest/" + tempFileName)); allfiles.last()->open(QIODevice::WriteOnly); } file.close(); while (!allfiles.isEmpty()) { auto tempDel = allfiles.takeLast(); tempDel->remove(); delete tempDel; } return 0;
0 Files. Time: 0.00
100 Files. Time: 0.03
200 Files. Time: 0.03
300 Files. Time: 0.03
400 Files. Time: 0.03
500 Files. Time: 0.03
600 Files. Time: 0.03
700 Files. Time: 0.03
800 Files. Time: 0.03
900 Files. Time: 0.03
1000 Files. Time: 0.03
1100 Files. Time: 0.03
1200 Files. Time: 0.03
1300 Files. Time: 0.03
1400 Files. Time: 0.03
1500 Files. Time: 0.03
1600 Files. Time: 0.03
1700 Files. Time: 0.03
1800 Files. Time: 0.03
1900 Files. Time: 0.03 -
I think creating temporary files is slower compared to creating new files, because Qt framework has to ensure that the file names are unique.
-
Why shouldn't it be fast? You only check whether a file exists or not. What QTemporaryFile is doing: it creates a unique file name and ensures nobody else creates one with the same name in the same directory. This, for sure, involves some OS calls to make the creation of a temp file an atomic operation. Else several processes could create and use a temp file with same file name.
-
@VRonin said in QTemporaryFile takes forever:
} while (QFile::exists("C:/temp/TempTest/" + tempFileName)); allfiles.append(new QFile("C:/temp/TempTest/" + tempFileName)); allfiles.last()->open(QIODevice::WriteOnly);
@VRonin I see that you wrote this in 2015. Leaving aside that if the timing you describe still holds then I am not sure why and yours is an interesting finding, looking at this code now would you recommend it for exclusively creating a file, in a multi-process environment? ;-)
-
@JonB The code above is not correct and can create a race condition since another thread/process can create exactly the same filename between QFile::exists() and open(). That's also the reason why the Qt implementation is slower - it opens a file and if it fails it checks some error conditions.
Also the possible space for the file names is lower in QTemporaryFile (only six digits by default) while the other loop is using 15 characters, so the chance of a collision is much lower. -
@Christian-Ehrlicher
It was the race condition that I had noticed. I was bringing that to @VRonin 's attention and seeing what he said about it, it's sometimes interesting to look back on your own code from years ago :)