From 148fc554cfcffbe44203b5034e7320a84567b0cc Mon Sep 17 00:00:00 2001 From: Julian Mesa Date: Wed, 13 Jul 2022 17:21:05 +0200 Subject: [PATCH] Optimize NodeGit objects creation. Getting the constructor template is slow, we can get a 30% gain creating NodeGit objects if we get the constructor template only once. --- .../manual/include/convenient_hunk.h | 2 ++ .../manual/include/convenient_patch.h | 2 ++ .../manual/include/nodegit_wrapper.h | 5 +++ .../manual/patches/convenient_patches.cc | 3 +- generate/templates/manual/remote/ls.cc | 3 +- .../manual/repository/get_references.cc | 5 ++- .../manual/repository/get_remotes.cc | 5 ++- .../manual/repository/get_submodules.cc | 5 ++- .../templates/manual/revwalk/commit_walk.cc | 8 +++-- .../templates/manual/revwalk/fast_walk.cc | 3 +- .../manual/revwalk/file_history_walk.cc | 9 +++-- .../templates/manual/src/convenient_hunk.cc | 11 +++++++ .../templates/manual/src/convenient_patch.cc | 14 +++++++- .../templates/manual/src/nodegit_wrapper.cc | 33 ++++++++++++++++++- .../partials/configurable_callbacks.cc | 3 +- 15 files changed, 97 insertions(+), 14 deletions(-) diff --git a/generate/templates/manual/include/convenient_hunk.h b/generate/templates/manual/include/convenient_hunk.h index c45da7368..fe19e096f 100644 --- a/generate/templates/manual/include/convenient_hunk.h +++ b/generate/templates/manual/include/convenient_hunk.h @@ -31,6 +31,8 @@ class ConvenientHunk : public Nan::ObjectWrap { static void InitializeComponent (v8::Local target, nodegit::Context *nodegitContext); static v8::Local New(void *raw); + static v8::Local New(v8::Local constructorTemplate, void *raw); + static v8::Local GetTemplate(); HunkData *GetValue(); char *GetHeader(); diff --git a/generate/templates/manual/include/convenient_patch.h b/generate/templates/manual/include/convenient_patch.h index a89476569..933412a86 100644 --- a/generate/templates/manual/include/convenient_patch.h +++ b/generate/templates/manual/include/convenient_patch.h @@ -46,7 +46,9 @@ class ConvenientPatch : public Nan::ObjectWrap { static void InitializeComponent(v8::Local target, nodegit::Context *nodegitContext); + static v8::Local GetTemplate(); static v8::Local New(void *raw); + static v8::Local New(v8::Local constructorTemplate, void *raw); ConvenientLineStats GetLineStats(); git_delta_t GetStatus(); diff --git a/generate/templates/manual/include/nodegit_wrapper.h b/generate/templates/manual/include/nodegit_wrapper.h index c72f29027..be564cd35 100644 --- a/generate/templates/manual/include/nodegit_wrapper.h +++ b/generate/templates/manual/include/nodegit_wrapper.h @@ -75,6 +75,11 @@ class NodeGitWrapper : public nodegit::TrackerWrap { public: static v8::Local New(const cType *raw, bool selfFreeing, v8::Local owner = v8::Local()); + static v8::Local New(v8::Local constructorTemplate,const cType *raw, bool selfFreeing, v8::Local owner); + static v8::Local New(v8::Local constructorTemplate,const cType *raw, bool selfFreeing); + + static v8::Local GetTemplate(); + void SaveCleanupHandle(std::shared_ptr cleanupHandle); diff --git a/generate/templates/manual/patches/convenient_patches.cc b/generate/templates/manual/patches/convenient_patches.cc index e183afb75..2404effa5 100644 --- a/generate/templates/manual/patches/convenient_patches.cc +++ b/generate/templates/manual/patches/convenient_patches.cc @@ -151,8 +151,9 @@ void GitPatch::ConvenientFromDiffWorker::HandleOKCallback() { unsigned int size = baton->out->size(); Local result = Nan::New(size); + v8::Local constructor_template = ConvenientPatch::GetTemplate(); for (unsigned int i = 0; i < size; ++i) { - Nan::Set(result, Nan::New(i), ConvenientPatch::New((void *)baton->out->at(i))); + Nan::Set(result, Nan::New(i), ConvenientPatch::New(constructor_template, (void *)baton->out->at(i))); } delete baton->out; diff --git a/generate/templates/manual/remote/ls.cc b/generate/templates/manual/remote/ls.cc index 97c801c62..2101924cb 100644 --- a/generate/templates/manual/remote/ls.cc +++ b/generate/templates/manual/remote/ls.cc @@ -72,8 +72,9 @@ void GitRemote::ReferenceListWorker::HandleOKCallback() { unsigned int size = baton->out->size(); Local result = Nan::New(size); + v8::Local constructor_template = GitRemoteHead::GetTemplate(); for (unsigned int i = 0; i < size; i++) { - Nan::Set(result, Nan::New(i), GitRemoteHead::New(baton->out->at(i), true)); + Nan::Set(result, Nan::New(i), GitRemoteHead::New(constructor_template, baton->out->at(i), true)); } delete baton->out; diff --git a/generate/templates/manual/repository/get_references.cc b/generate/templates/manual/repository/get_references.cc index 1db6c542f..6bcb25da3 100644 --- a/generate/templates/manual/repository/get_references.cc +++ b/generate/templates/manual/repository/get_references.cc @@ -108,15 +108,18 @@ void GitRepository::GetReferencesWorker::HandleOKCallback() { unsigned int size = baton->out->size(); Local result = Nan::New(size); + v8::Local git_refs_template = GitRefs::GetTemplate(); + v8::Local git_repository_template = GitRepository::GetTemplate(); for (unsigned int i = 0; i < size; i++) { git_reference *reference = baton->out->at(i); Nan::Set( result, Nan::New(i), GitRefs::New( + git_refs_template, reference, true, - Nan::To(GitRepository::New(git_reference_owner(reference), true)).ToLocalChecked() + Nan::To(GitRepository::New(git_repository_template, git_reference_owner(reference), true)).ToLocalChecked() ) ); } diff --git a/generate/templates/manual/repository/get_remotes.cc b/generate/templates/manual/repository/get_remotes.cc index 647498837..a750cf53f 100644 --- a/generate/templates/manual/repository/get_remotes.cc +++ b/generate/templates/manual/repository/get_remotes.cc @@ -110,15 +110,18 @@ void GitRepository::GetRemotesWorker::HandleOKCallback() { unsigned int size = baton->out->size(); Local result = Nan::New(size); + v8::Local git_remote_template = GitRemote::GetTemplate(); + v8::Local git_repository_template = GitRepository::GetTemplate(); for (unsigned int i = 0; i < size; i++) { git_remote *remote = baton->out->at(i); Nan::Set( result, Nan::New(i), GitRemote::New( + git_remote_template, remote, true, - Nan::To(GitRepository::New(git_remote_owner(remote), true)).ToLocalChecked() + Nan::To(GitRepository::New(git_repository_template, git_remote_owner(remote), true)).ToLocalChecked() ) ); } diff --git a/generate/templates/manual/repository/get_submodules.cc b/generate/templates/manual/repository/get_submodules.cc index 069f6bdbc..2c3e08bfd 100644 --- a/generate/templates/manual/repository/get_submodules.cc +++ b/generate/templates/manual/repository/get_submodules.cc @@ -88,15 +88,18 @@ void GitRepository::GetSubmodulesWorker::HandleOKCallback() { unsigned int size = baton->out->size(); Local result = Nan::New(size); + v8::Local git_submodule_template = GitSubmodule::GetTemplate(); + v8::Local git_repository_template = GitRepository::GetTemplate(); for (unsigned int i = 0; i < size; i++) { git_submodule *submodule = baton->out->at(i); Nan::Set( result, Nan::New(i), GitSubmodule::New( + git_submodule_template, submodule, true, - Nan::To(GitRepository::New(git_submodule_owner(submodule), true)).ToLocalChecked() + Nan::To(GitRepository::New(git_repository_template, git_submodule_owner(submodule), true)).ToLocalChecked() ) ); } diff --git a/generate/templates/manual/revwalk/commit_walk.cc b/generate/templates/manual/revwalk/commit_walk.cc index 4fe60de9e..774bfad6a 100644 --- a/generate/templates/manual/revwalk/commit_walk.cc +++ b/generate/templates/manual/revwalk/commit_walk.cc @@ -45,12 +45,14 @@ class CommitModel { CommitModel &operator=(const CommitModel &) = delete; CommitModel &operator=(CommitModel &&) = delete; - v8::Local toJavascript() { + v8::Local toJavascript(v8::Local GitCommitTemplate, v8::Local GitRepositoryTemplate) { if (!fetchSignature) { v8::Local commitObject = GitCommit::New( + GitCommitTemplate, commit, true, Nan::To(GitRepository::New( + GitRepositoryTemplate, git_commit_owner(commit), true )).ToLocalChecked() @@ -232,12 +234,14 @@ void GitRevwalk::CommitWalkWorker::HandleOKCallback() { std::vector *out = static_cast *>(baton->out); const unsigned int size = out->size(); Local result = Nan::New(size); + v8::Local git_commit_template = GitCommit::GetTemplate(); + v8::Local git_repository_template = GitRepository::GetTemplate(); for (unsigned int i = 0; i < size; i++) { CommitModel *commitModel = out->at(i); Nan::Set( result, Nan::New(i), - commitModel->toJavascript() + commitModel->toJavascript(git_commit_template, git_repository_template) ); delete commitModel; } diff --git a/generate/templates/manual/revwalk/fast_walk.cc b/generate/templates/manual/revwalk/fast_walk.cc index ce2d05a2d..ad7be8516 100644 --- a/generate/templates/manual/revwalk/fast_walk.cc +++ b/generate/templates/manual/revwalk/fast_walk.cc @@ -98,8 +98,9 @@ void GitRevwalk::FastWalkWorker::HandleOKCallback() { unsigned int size = baton->out->size(); Local result = Nan::New(size); + v8::Local constructor_template = GitOid::GetTemplate(); for (unsigned int i = 0; i < size; i++) { - Nan::Set(result, Nan::New(i), GitOid::New(baton->out->at(i), true)); + Nan::Set(result, Nan::New(i), GitOid::New(constructor_template, baton->out->at(i), true)); } delete baton->out; diff --git a/generate/templates/manual/revwalk/file_history_walk.cc b/generate/templates/manual/revwalk/file_history_walk.cc index 714d6f5db..ffd856987 100644 --- a/generate/templates/manual/revwalk/file_history_walk.cc +++ b/generate/templates/manual/revwalk/file_history_walk.cc @@ -33,18 +33,19 @@ class FileHistoryEvent { } } - v8::Local toJavascript() { + v8::Local toJavascript(v8::Local GitCommitTemplate, v8::Local GitRepositoryTemplate) { v8::Local historyEntry = Nan::New(); v8::Local owners = Nan::New(0); Nan::Set( owners, Nan::New(owners->Length()), Nan::To(GitRepository::New( + GitRepositoryTemplate, git_commit_owner(commit), true )).ToLocalChecked() ); - Nan::Set(historyEntry, Nan::New("commit").ToLocalChecked(), GitCommit::New(commit, true, owners)); + Nan::Set(historyEntry, Nan::New("commit").ToLocalChecked(), GitCommit::New(GitCommitTemplate, commit, true, owners)); commit = NULL; Nan::Set(historyEntry, Nan::New("status").ToLocalChecked(), Nan::New(type)); Nan::Set(historyEntry, Nan::New("isMergeCommit").ToLocalChecked(), Nan::New(isMergeCommit)); @@ -455,9 +456,11 @@ void GitRevwalk::FileHistoryWalkWorker::HandleOKCallback() if (baton->out != NULL) { const unsigned int size = baton->out->size(); v8::Local result = Nan::New(size); + v8::Local git_commit_template = GitCommit::GetTemplate(); + v8::Local git_repository_template = GitRepository::GetTemplate(); for (unsigned int i = 0; i < size; i++) { FileHistoryEvent *batonResult = static_cast(baton->out->at(i)); - Nan::Set(result, Nan::New(i), batonResult->toJavascript()); + Nan::Set(result, Nan::New(i), batonResult->toJavascript(git_commit_template, git_repository_template)); delete batonResult; } diff --git a/generate/templates/manual/src/convenient_hunk.cc b/generate/templates/manual/src/convenient_hunk.cc index 38dd8c078..674e7ebc4 100644 --- a/generate/templates/manual/src/convenient_hunk.cc +++ b/generate/templates/manual/src/convenient_hunk.cc @@ -77,6 +77,17 @@ Local ConvenientHunk::New(void *raw) { return scope.Escape(Nan::NewInstance(constructor_template, 1, argv).ToLocalChecked()); } +Local ConvenientHunk::New(v8::Local constructorTemplate, void *raw) { + Nan::EscapableHandleScope scope; + Local argv[1] = { Nan::New((void *)raw) }; + return scope.Escape(Nan::NewInstance(constructorTemplate, 1, argv).ToLocalChecked()); +} + +v8::Local ConvenientHunk::GetTemplate() { + nodegit::Context *nodegitContext = nodegit::Context::GetCurrentContext(); + return nodegitContext->GetFromPersistent("ConvenientHunk::Template").As(); +} + HunkData *ConvenientHunk::GetValue() { return this->hunk; } diff --git a/generate/templates/manual/src/convenient_patch.cc b/generate/templates/manual/src/convenient_patch.cc index f60f53257..bd2b54aa2 100644 --- a/generate/templates/manual/src/convenient_patch.cc +++ b/generate/templates/manual/src/convenient_patch.cc @@ -183,6 +183,17 @@ Local ConvenientPatch::New(void *raw) { return scope.Escape(Nan::NewInstance(constructor_template, 1, argv).ToLocalChecked()); } +Local ConvenientPatch::New(v8::Local constructorTemplate, void *raw) { + Nan::EscapableHandleScope scope; + Local argv[1] = { Nan::New((void *)raw) }; + return scope.Escape(Nan::NewInstance(constructorTemplate, 1, argv).ToLocalChecked()); +} + +v8::Local ConvenientPatch::GetTemplate() { + nodegit::Context *nodegitContext = nodegit::Context::GetCurrentContext(); + return nodegitContext->GetFromPersistent("ConvenientPatch::Template").As(); +} + ConvenientLineStats ConvenientPatch::GetLineStats() { return this->patch->lineStats; } @@ -280,8 +291,9 @@ void ConvenientPatch::HunksWorker::HandleOKCallback() { unsigned int size = baton->hunks->size(); Local result = Nan::New(size); + v8::Local constructor_template = ConvenientHunk::GetTemplate(); for(unsigned int i = 0; i < size; ++i) { - Nan::Set(result, Nan::New(i), ConvenientHunk::New(baton->hunks->at(i))); + Nan::Set(result, Nan::New(i), ConvenientHunk::New(constructor_template, baton->hunks->at(i))); } delete baton->hunks; diff --git a/generate/templates/manual/src/nodegit_wrapper.cc b/generate/templates/manual/src/nodegit_wrapper.cc index a790d7bc3..f8da7ccb1 100644 --- a/generate/templates/manual/src/nodegit_wrapper.cc +++ b/generate/templates/manual/src/nodegit_wrapper.cc @@ -87,7 +87,7 @@ template void NodeGitWrapper::SetNativeOwners(v8::Local owners) { assert(owners->IsArray() || owners->IsObject()); Nan::HandleScope scope; - std::unique_ptr< std::vector > trackerOwners = + std::unique_ptr< std::vector > trackerOwners = std::make_unique< std::vector >(); if (owners->IsArray()) { @@ -126,6 +126,37 @@ v8::Local NodeGitWrapper::New(const typename Traits::cType *r ).ToLocalChecked()); } +template +v8::Local NodeGitWrapper::New(v8::Local constructorTemplate, const typename Traits::cType *raw, bool selfFreeing, v8::Local owner) { + Nan::EscapableHandleScope scope; + Local argv[3] = { Nan::New((void *)raw), Nan::New(selfFreeing), owner }; + return scope.Escape( + Nan::NewInstance( + constructorTemplate, + 3, + argv + ).ToLocalChecked()); +} + +template +v8::Local NodeGitWrapper::New(v8::Local constructorTemplate, const typename Traits::cType *raw, bool selfFreeing) { + Nan::EscapableHandleScope scope; + Local argv[2] = { Nan::New((void *)raw), Nan::New(selfFreeing) }; + return scope.Escape( + Nan::NewInstance( + constructorTemplate, + 2, + argv + ).ToLocalChecked()); +} + +template +v8::Local NodeGitWrapper::GetTemplate() { + return nodegit::Context::GetCurrentContext()->GetFromPersistent( + std::string(Traits::className()) + "::Template" + ).As(); +} + template typename Traits::cType *NodeGitWrapper::GetValue() { return raw; diff --git a/generate/templates/partials/configurable_callbacks.cc b/generate/templates/partials/configurable_callbacks.cc index 79eef554b..028e32e7f 100644 --- a/generate/templates/partials/configurable_callbacks.cc +++ b/generate/templates/partials/configurable_callbacks.cc @@ -87,8 +87,9 @@ {% each field.args|callbackArgsInfo as arg %} {% if arg.cppClassName == "Array" %} v8::Local _{{arg.name}}_array = Nan::New(baton->{{ arg.arrayLengthArgumentName }}); + v8::Local constructor_template = {{arg.arrayElementCppClassName}}::GetTemplate(); for(uint32_t i = 0; i < _{{arg.name}}_array->Length(); i++) { - Nan::Set(_{{arg.name}}_array, i, {{arg.arrayElementCppClassName}}::New(baton->{{arg.name}}[i], false)); + Nan::Set(_{{arg.name}}_array, i, {{arg.arrayElementCppClassName}}::New(constructor_template, baton->{{arg.name}}[i], false)); } {% endif %} {% endeach %}