forked from Mirrors/openclonk
Win32: Drastically improve load times with unpacked planet/
C4Group::SearchNextEntry would waste lots of cycles looking up file attributes that were never inspected afterwards. Since all we want is the file size, and we already get that for free from FindFirstFile and FindNextFile, store it with the directory iterator instead of querying it at every iteration. This reduces load times on my machine by almost half, tested across several different scenarios.qteditor
parent
0ad8e15c8a
commit
e490428f29
|
@ -422,7 +422,7 @@ void C4GroupEntry::Set(const DirectoryIterator &iter, const char * path)
|
|||
|
||||
SCopy(GetFilename(*iter),FileName,_MAX_FNAME);
|
||||
SCopy(*iter, DiskPath, _MAX_PATH-1);
|
||||
Size = FileSize(*iter);
|
||||
Size = iter.GetFileSize();
|
||||
Status=C4GRES_OnDisk;
|
||||
Packed=false;
|
||||
ChildGroup=false;
|
||||
|
|
|
@ -989,7 +989,10 @@ void DirectoryIterator::Read(const char *dirname)
|
|||
// ...unless they're . or ..
|
||||
if (file.cFileName[0] == '.' && (file.cFileName[1] == '\0' || (file.cFileName[1] == '.' && file.cFileName[2] == '\0')))
|
||||
continue;
|
||||
p->files.push_back(StdStrBuf(file.cFileName).getData());
|
||||
|
||||
size_t size = (file.nFileSizeHigh * (size_t(MAXDWORD) + 1)) + file.nFileSizeLow;
|
||||
|
||||
p->files.emplace_back(StdStrBuf(file.cFileName).getData(), size);
|
||||
}
|
||||
while (FindNextFileW(fh, &file));
|
||||
FindClose(fh);
|
||||
|
@ -1016,14 +1019,14 @@ void DirectoryIterator::Read(const char *dirname)
|
|||
// ...unless they're . or ..
|
||||
if (file->d_name[0] == '.' && (file->d_name[1] == '\0' || (file->d_name[1] == '.' && file->d_name[2] == '\0')))
|
||||
continue;
|
||||
p->files.push_back(file->d_name);
|
||||
p->files.emplace_back(file->d_name, 0);
|
||||
}
|
||||
closedir(fh);
|
||||
#endif
|
||||
// Sort list
|
||||
std::sort(p->files.begin(), p->files.end());
|
||||
for (FileList::iterator it = p->files.begin(); it != p->files.end(); ++it)
|
||||
it->insert(0, search_path); // prepend path to all file entries
|
||||
it->first.insert(0, search_path); // prepend path to all file entries
|
||||
iter = p->files.begin();
|
||||
p->directory = dirname;
|
||||
}
|
||||
|
@ -1039,7 +1042,7 @@ const char * DirectoryIterator::operator*() const
|
|||
{
|
||||
if (iter == p->files.end())
|
||||
return NULL;
|
||||
return iter->c_str();
|
||||
return iter->first.c_str();
|
||||
}
|
||||
DirectoryIterator DirectoryIterator::operator++(int)
|
||||
{
|
||||
|
@ -1048,6 +1051,15 @@ DirectoryIterator DirectoryIterator::operator++(int)
|
|||
return tmp;
|
||||
}
|
||||
|
||||
size_t DirectoryIterator::GetFileSize() const
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return iter->second;
|
||||
#else
|
||||
return FileSize(iter->first.c_str());
|
||||
#endif
|
||||
}
|
||||
|
||||
int ForEachFile(const char *szDirName, bool (*fnCallback)(const char *))
|
||||
{
|
||||
if (!szDirName || !fnCallback)
|
||||
|
|
|
@ -94,6 +94,9 @@ public:
|
|||
~DirectoryIterator();
|
||||
|
||||
const char * operator * () const;
|
||||
const char *GetName() const { return **this; }
|
||||
size_t GetFileSize() const;
|
||||
|
||||
DirectoryIterator& operator ++ ();
|
||||
DirectoryIterator operator ++ (int);
|
||||
void Clear(); // put iterator into empty state and clear any cached directory listing
|
||||
|
@ -102,7 +105,7 @@ public:
|
|||
private:
|
||||
void Read(const char *dirname);
|
||||
friend struct DirectoryIteratorP;
|
||||
typedef std::vector<std::string> FileList;
|
||||
typedef std::vector<std::pair<std::string, size_t>> FileList;
|
||||
DirectoryIteratorP *p;
|
||||
FileList::iterator iter;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue