Speed up ObjC Generation with large dependency trees

Don't create FileGenerators for each dep. FileGenerators will deeply create all
the message, enum, and field generators; but those aren't needed when doing
the imports for dependencies. Instead directly generate the imports off the
FileDescriptors so no extra objects are created. The only other use was when
chaining together the *Roots for the file extension registry, but that also
can be generate off the name of the FileDescriptor directly.
pull/2031/head
Thomas Van Lenten 9 years ago
parent e721ce66cf
commit 78a6d310de
  1. 55
      src/google/protobuf/compiler/objectivec/objectivec_file.cc
  2. 13
      src/google/protobuf/compiler/objectivec/objectivec_file.h

@ -59,7 +59,6 @@ namespace objectivec {
FileGenerator::FileGenerator(const FileDescriptor *file, const Options& options) FileGenerator::FileGenerator(const FileDescriptor *file, const Options& options)
: file_(file), : file_(file),
root_class_name_(FileClassName(file)), root_class_name_(FileClassName(file)),
is_public_dep_(false),
options_(options) { options_(options) {
for (int i = 0; i < file_->enum_type_count(); i++) { for (int i = 0; i < file_->enum_type_count(); i++) {
EnumGenerator *generator = new EnumGenerator(file_->enum_type(i)); EnumGenerator *generator = new EnumGenerator(file_->enum_type(i));
@ -78,8 +77,6 @@ FileGenerator::FileGenerator(const FileDescriptor *file, const Options& options)
} }
FileGenerator::~FileGenerator() { FileGenerator::~FileGenerator() {
STLDeleteContainerPointers(dependency_generators_.begin(),
dependency_generators_.end());
STLDeleteContainerPointers(enum_generators_.begin(), enum_generators_.end()); STLDeleteContainerPointers(enum_generators_.begin(), enum_generators_.end());
STLDeleteContainerPointers(message_generators_.begin(), STLDeleteContainerPointers(message_generators_.begin(),
message_generators_.end()); message_generators_.end());
@ -105,14 +102,9 @@ void FileGenerator::GenerateHeader(io::Printer *printer) {
ImportWriter import_writer( ImportWriter import_writer(
options_.generate_for_named_framework, options_.generate_for_named_framework,
options_.named_framework_to_proto_path_mappings_path); options_.named_framework_to_proto_path_mappings_path);
const vector<FileGenerator *> &dependency_generators = DependencyGenerators();
const string header_extension(kHeaderExtension); const string header_extension(kHeaderExtension);
for (vector<FileGenerator *>::const_iterator iter = for (int i = 0; i < file_->public_dependency_count(); i++) {
dependency_generators.begin(); import_writer.AddFile(file_->public_dependency(i), header_extension);
iter != dependency_generators.end(); ++iter) {
if ((*iter)->IsPublicDependency()) {
import_writer.AddFile((*iter)->file_, header_extension);
}
} }
import_writer.Print(printer); import_writer.Print(printer);
} }
@ -223,13 +215,15 @@ void FileGenerator::GenerateSource(io::Printer *printer) {
// #import the headers for anything that a plain dependency of this proto // #import the headers for anything that a plain dependency of this proto
// file (that means they were just an include, not a "public" include). // file (that means they were just an include, not a "public" include).
const vector<FileGenerator *> &dependency_generators = set<string> public_import_names;
DependencyGenerators(); for (int i = 0; i < file_->public_dependency_count(); i++) {
for (vector<FileGenerator *>::const_iterator iter = public_import_names.insert(file_->public_dependency(i)->name());
dependency_generators.begin(); }
iter != dependency_generators.end(); ++iter) { for (int i = 0; i < file_->dependency_count(); i++) {
if (!(*iter)->IsPublicDependency()) { const FileDescriptor *dep = file_->dependency(i);
import_writer.AddFile((*iter)->file_, header_extension); bool public_import = (public_import_names.count(dep->name()) != 0);
if (!public_import) {
import_writer.AddFile(dep, header_extension);
} }
} }
@ -321,14 +315,11 @@ void FileGenerator::GenerateSource(io::Printer *printer) {
"}\n"); "}\n");
} }
const vector<FileGenerator *> &dependency_generators = for (int i = 0; i < file_->dependency_count(); i++) {
DependencyGenerators(); const string root_class_name(FileClassName(file_->dependency(i)));
for (vector<FileGenerator *>::const_iterator iter =
dependency_generators.begin();
iter != dependency_generators.end(); ++iter) {
printer->Print( printer->Print(
"[registry addExtensions:[$dependency$ extensionRegistry]];\n", "[registry addExtensions:[$dependency$ extensionRegistry]];\n",
"dependency", (*iter)->RootClassName()); "dependency", root_class_name);
} }
printer->Outdent(); printer->Outdent();
@ -393,24 +384,6 @@ void FileGenerator::GenerateSource(io::Printer *printer) {
"// @@protoc_insertion_point(global_scope)\n"); "// @@protoc_insertion_point(global_scope)\n");
} }
const vector<FileGenerator *> &FileGenerator::DependencyGenerators() {
if (file_->dependency_count() != dependency_generators_.size()) {
set<string> public_import_names;
for (int i = 0; i < file_->public_dependency_count(); i++) {
public_import_names.insert(file_->public_dependency(i)->name());
}
for (int i = 0; i < file_->dependency_count(); i++) {
FileGenerator *generator =
new FileGenerator(file_->dependency(i), options_);
const string& name = file_->dependency(i)->name();
bool public_import = (public_import_names.count(name) != 0);
generator->SetIsPublicDependency(public_import);
dependency_generators_.push_back(generator);
}
}
return dependency_generators_;
}
// Helper to print the import of the runtime support at the top of generated // Helper to print the import of the runtime support at the top of generated
// files. This currently only supports the runtime coming from a framework // files. This currently only supports the runtime coming from a framework
// as defined by the official CocoaPod. // as defined by the official CocoaPod.

@ -63,29 +63,16 @@ class FileGenerator {
const string& RootClassName() const { return root_class_name_; } const string& RootClassName() const { return root_class_name_; }
bool IsPublicDependency() const { return is_public_dep_; }
protected:
void SetIsPublicDependency(bool is_public_dep) {
is_public_dep_ = is_public_dep;
}
private: private:
const FileDescriptor* file_; const FileDescriptor* file_;
string root_class_name_; string root_class_name_;
// Access this field through the DependencyGenerators accessor call below.
// Do not reference it directly.
vector<FileGenerator*> dependency_generators_;
vector<EnumGenerator*> enum_generators_; vector<EnumGenerator*> enum_generators_;
vector<MessageGenerator*> message_generators_; vector<MessageGenerator*> message_generators_;
vector<ExtensionGenerator*> extension_generators_; vector<ExtensionGenerator*> extension_generators_;
bool is_public_dep_;
const Options options_; const Options options_;
const vector<FileGenerator*>& DependencyGenerators();
void PrintFileRuntimePreamble( void PrintFileRuntimePreamble(
io::Printer* printer, const string& header_to_import) const; io::Printer* printer, const string& header_to_import) const;

Loading…
Cancel
Save