diff --git a/src/backend/game/game.cpp b/src/backend/game/game.cpp index 2ba29e01..9ef05447 100644 --- a/src/backend/game/game.cpp +++ b/src/backend/game/game.cpp @@ -123,17 +123,26 @@ namespace loot { } void Game::LoadPlugins(bool headersOnly) { - // First find out how many plugins there are. + uintmax_t meanFileSize = 0; + map sizeMap; + + // First find out how many plugins there are, and their sizes. BOOST_LOG_TRIVIAL(trace) << "Scanning for plugins in " << this->DataPath(); for (fs::directory_iterator it(this->DataPath()); it != fs::directory_iterator(); ++it) { if (fs::is_regular_file(it->status()) && Plugin(it->path().filename().string()).IsValid(*this)) { Plugin temp(it->path().filename().string()); BOOST_LOG_TRIVIAL(info) << "Found plugin: " << temp.Name(); + uintmax_t fileSize = fs::file_size(it->path()); + meanFileSize += fileSize; + //Insert the lowercased name as a key for case-insensitive matching. - plugins.insert(pair(boost::locale::to_lower(temp.Name()), temp)); + std::string name = boost::locale::to_lower(temp.Name()); + plugins.insert(pair(name, temp)); + sizeMap.insert(pair(fileSize, name)); } } + meanFileSize /= sizeMap.size(); //Rounding error, but not important. // Get the number of threads to use. // hardware_concurrency() may be zero, if so then use only one thread. @@ -142,16 +151,18 @@ namespace loot { // Divide the plugins up by thread. unsigned int pluginsPerThread = ceil((double)plugins.size() / threadsToUse); + std::vector::iterator>> pluginGroups(threadsToUse); BOOST_LOG_TRIVIAL(info) << "Loading " << plugins.size() << " plugins using " << threadsToUse << " threads, with up to " << pluginsPerThread << " plugins per thread."; - std::vector::iterator>> pluginGroups(threadsToUse); - size_t pluginGroup = 0; - for (auto it = plugins.begin(); it != plugins.end(); ++it) { - if (pluginGroups[pluginGroup].size() == pluginsPerThread) { - ++pluginGroup; - } - BOOST_LOG_TRIVIAL(trace) << "Adding plugin " << it->second.Name() << " to loading group " << pluginGroup; - pluginGroups[pluginGroup].push_back(it); + // The plugins should be split between the threads so that the data + // load is as evenly spread as possible. + size_t currentGroup = 0; + for (auto& plugin : sizeMap) { + if (currentGroup == threadsToUse) + currentGroup = 0; + BOOST_LOG_TRIVIAL(trace) << "Adding plugin " << plugin.second << " to loading group " << currentGroup; + pluginGroups[currentGroup].push_back(plugins.find(plugin.second)); + ++currentGroup; } // Load the plugins.