View Issue Details Jump to Notes ] Print ]
IDProjectCategoryView StatusDate SubmittedLast Update
0015201CMakeCMakepublic2014-10-09 11:072015-05-04 09:05
ReporterKnuckles The Dog 
Assigned ToBen Boeckel 
PrioritynormalSeveritymajorReproducibilityalways
StatusclosedResolutionfixed 
PlatformApple MacOSOS X 10.9OS Version10.9
Product VersionCMake 3.0.2 
Target VersionCMake 3.2Fixed in VersionCMake 3.2 
Summary0015201: Xcode generator is unusably slow on large projects
DescriptionI am building a large project, over a thousand CMakeList.txt files resulting in hundreds of Xcode projects being generated. This takes at least 6 times longer than the same makefile generation.

I have profiled cmake 3.0.2 and found a significant bottleneck in cmGlobalXCodeGenerator::FindXCodeTarget() because the objects are stored in a vector and this vector has to be iterated over each time to find a target. This is done thousands of times in the course of generating the Xcode project.

As a quick fix I did the following:

cmGlobalXCodeGenerator.h, added member var:
std::unordered_map<const cmTarget*, cmXCodeObject*> mXcodeObjectMap;

cmGlobalXCodeGenerator.cpp
void cmGlobalXCodeGenerator::ClearXCodeObjects()
added to end of method: mXcodeObjectMap.clear();

cmGlobalXCodeGenerator::CreateUtilityTarget(cmTarget& cmtarget)
Under call to target->SetTarget(...) added: mXcodeObjectMap[&cmtarget] = target;

cmGlobalXCodeGenerator::CreateXCodeTarget(...)
Under call to target->SetTarget(...) added: mXcodeObjectMap[&cmtarget] = target;

cmXCodeObject* cmGlobalXCodeGenerator::FindXCodeTarget(cmTarget const* t)
rewrote to:
cmXCodeObject* cmGlobalXCodeGenerator::FindXCodeTarget(cmTarget const* t)
{
  if(!t)
    {
    return 0;
    }
  
  std::unordered_map<const cmTarget*, cmXCodeObject*>::iterator iter = mXcodeObjectMap.find(t);
  if (iter == mXcodeObjectMap.end())
  {
    return 0;
  }
  return iter->second;
}
So basically rather than constantly iterating through a vector for the Xcode object with the right target, it now keeps an unordered map where the key is the target pointer, and the object is the Xcode object. This reduces the lookup time enormously.

With only this change the generation of the project I'm working on goes down from well over an hour to around 10 mins, which puts it inline with the makefile generator performance.
Steps To ReproduceBuild a large set of projects.
TagsNo tags attached.
Attached Files

 Relationships

  Notes
(0037337)
Ben Boeckel (developer)
2014-12-01 12:59

I've made a patch and merged it to next which does a similar thing (it uses std::map instead). std::unordered_map is not available on all of CMake's targets and a pointer compare is pretty cheap (not as cheap as a hash on it, but better than std::string compares at least.
(0037358)
Brad King (manager)
2014-12-02 11:17

Re 0015201:0037337: After one fixup the patch is now a commit here:

 Xcode: use a map to look up target pointers
 http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=48f78f5f [^]
(0038687)
Robert Maynard (manager)
2015-05-04 09:05

Closing resolved issues that have not been updated in more than 4 months.

 Issue History
Date Modified Username Field Change
2014-10-09 11:07 Knuckles The Dog New Issue
2014-10-09 11:12 Brad King Assigned To => Ben Boeckel
2014-10-09 11:12 Brad King Status new => assigned
2014-10-09 11:12 Brad King Target Version => CMake 3.2
2014-12-01 12:59 Ben Boeckel Note Added: 0037337
2014-12-01 12:59 Ben Boeckel Status assigned => acknowledged
2014-12-02 11:17 Brad King Note Added: 0037358
2014-12-02 11:17 Brad King Status acknowledged => resolved
2014-12-02 11:17 Brad King Resolution open => fixed
2014-12-02 11:17 Brad King Fixed in Version => CMake 3.2
2015-05-04 09:05 Robert Maynard Note Added: 0038687
2015-05-04 09:05 Robert Maynard Status resolved => closed


Copyright © 2000 - 2018 MantisBT Team