From 6383a4451edc3c576c7b572a15dbdca191901312 Mon Sep 17 00:00:00 2001 From: zhao lu Date: Sun, 4 Jul 2021 22:46:28 +0800 Subject: [PATCH 1/2] improve the efficiency of AddVMerged(const TVec&) in snap-core/ds.h. (tested) --- glib-core/ds.h | 13 ++++- test/Makefile | 3 +- test/test-TVec.cpp | 122 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 136 insertions(+), 2 deletions(-) create mode 100644 test/test-TVec.cpp diff --git a/glib-core/ds.h b/glib-core/ds.h index 90c525680..c8fa63146 100644 --- a/glib-core/ds.h +++ b/glib-core/ds.h @@ -1059,7 +1059,18 @@ template TSizeTy TVec::AddVMerged(const TVec& ValV){ EAssertR(!(IsShM && (MxVals == -1)), "Cannot write to shared memory"); AssertR(MxVals!=-1, "This vector was obtained from TVecPool. Such vectors cannot change its size!"); - for (TSizeTy ValN=0; ValN ValV2; + for (TSizeTy ValN=0; ValN ValNV; TSizeTy ValN=0; + for (TSizeTy ValN2 = 0; ValN2 < ValV2.Len(); ValN2++){ + for (; ValN ValV2[ValN2]){ValNV.Add(ValN); break;}}} + TSizeTy EndValN = Len()-1; TSizeTy OutValN = ValV2.Len() - ValNV.Len(); + for (TSizeTy N = 0; N < ValV2.Len() - OutValN; N++){Add();} + for (TSizeTy N = 0; N < OutValN; N++){Add(ValV2[ValNV.Len()+N]);} + for (TSizeTy ValN2 = ValNV.Len()-1; ValN2 >= 0; ValN2--) { + const TSizeTy & BegValN = ValNV[ValN2]; const TSizeTy OffSet = ValN2+1; + for (; EndValN >= BegValN; EndValN--){GetVal(EndValN+OffSet) = GetVal(EndValN);} + EndValN = BegValN + OffSet - 1; GetVal(EndValN) = ValV2[ValN2]; EndValN = BegValN - 1;} return Len(); } diff --git a/test/Makefile b/test/Makefile index 0f8679f1e..d4d13bf58 100644 --- a/test/Makefile +++ b/test/Makefile @@ -47,7 +47,8 @@ TEST_SRCS = \ test-flow.cpp \ test-randwalk.cpp \ test-priority-queue.cpp \ - test-sim.cpp + test-sim.cpp \ + test-TVec.cpp TEST_OBJS = $(TEST_SRCS:.cpp=.o) diff --git a/test/test-TVec.cpp b/test/test-TVec.cpp new file mode 100644 index 000000000..f3ed40656 --- /dev/null +++ b/test/test-TVec.cpp @@ -0,0 +1,122 @@ +#include + +#include +#include "Snap.h" +using namespace std; + +template +bool TestTVecEqual(const TVec& V1, const TVec& V2); + + +TEST(TVecTest, TIntVMergeV) { + +// Merge with unsorted normal TIntV + TIntV V1; V1.Add(1); V1.Add(2); V1.Add(3); V1.Add(5); + TIntV V2; V2.Add(7); V2.Add(4); V2.Add(5); V2.Add(2); + TIntV V3; V3.Add(1); V3.Add(2); V3.Add(3); V3.Add(4); V3.Add(5); V3.Add(7); + V1.AddVMerged(V2); + EXPECT_TRUE(TestTVecEqual(V1, V3)); + + // Merge with sorted normal TIntV + V1.Clr(); V1.Add(1); V1.Add(2); V1.Add(3); V1.Add(5); + V2.Clr(); V2.Add(0); V2.Add(2); V2.Add(4); V2.Add(6); + V3.Clr(); V3.Add(0); V3.Add(1); V3.Add(2); V3.Add(3); V3.Add(4); V3.Add(5); V3.Add(6); + V1.AddVMerged(V2); + EXPECT_TRUE(TestTVecEqual(V1, V3)); + + // Merge with more interleavings + V1.Clr(); V1.Add(1); V1.Add(3); V1.Add(5); V1.Add(9); V1.Add(10); + V2.Clr(); V2.Add(13); V2.Add(11); V2.Add(12); V2.Add(0); V2.Add(8); V2.Add(6); V2.Add(4); V2.Add(7); V2.Add(2); + V3.Clr(); + for (int i = 0; i < 14; i++) { + V3.Add(i); + } + V1.AddVMerged(V2); + EXPECT_TRUE(TestTVecEqual(V1, V3)); + + + // Merge with more interleavings and without overlapping + V1.Clr(); V1.Add(1); V1.Add(3); V1.Add(5); V1.Add(9); V1.Add(10); + V2.Clr(); V2.Add(13); V2.Add(11); V2.Add(12); V2.Add(0); V2.Add(8); V2.Add(6); V2.Add(4); V2.Add(7); V2.Add(2); + V2.Add(12); V2.Add(0); V2.Add(8); V2.Add(6); + V3.Clr(); + for (int i = 0; i < 14; i++) { + V3.Add(i); + } + V1.AddVMerged(V2); + EXPECT_TRUE(TestTVecEqual(V1, V3)); + + // Merge empty TIntV + V1.Clr(); V1.Add(1); V1.Add(2); V1.Add(3); + V2.Clr(); + V3 = V1; + V1.AddVMerged(V2); + EXPECT_TRUE(TestTVecEqual(V1, V3)); + + + // Empty TIntV merges with another normal TIntV + V2.AddVMerged(V1); + EXPECT_TRUE(TestTVecEqual(V2, V3)); + + // Merge the same TIntV + V2.AddVMerged(V3); + EXPECT_TRUE(TestTVecEqual(V2, V3)); + + // Merge two empty TIntV + V1.Clr(); + V2.Clr(); + V3.Clr(); + V1.AddVMerged(V3); + EXPECT_TRUE(TestTVecEqual(V2, V3)); +} + +template +bool TestTVecEqual(const TVec& V1, const TVec& V2){ + bool Result = true; + EXPECT_EQ(V1.Len(), V2.Len()); + Result &= V1.Len() == V2.Len(); + for (TInt ValN = 0; Result && ValN < V1.Len(); ValN++) { + EXPECT_EQ(V1[ValN], V2[ValN]); + Result = Result && (V1[ValN] == V2[ValN]); + } + return Result; +} + +#include +void TestNewMethodEfficiency(){ + const int Len1 = 10240; + const int Len2 = 10240; + const int Round = 1024; + TIntV V1; + TIntV V2; + double old_method_seconds = 0.0; + double new_method_seconds = 0.0; + for (int j = 0; j < Round; ++j) { + std::cout << "* " << j << endl; + V1.Clr(); V2.Clr(); + for (int k = 0; k < Len1; ++k) { + V1.Add(rand() % Len1); + } + for (int k = 0; k < Len2; ++k) { + V2.Add(rand() % Len1); + } + V1.Sort(); + TIntV V3 = V1; + auto start = chrono::system_clock::now(); + V1.AddVMerged(V2); + auto end = chrono::system_clock::now(); + chrono::duration seconds = end - start; + new_method_seconds += seconds.count(); + + start = chrono::system_clock::now(); + for (TInt ValN=0; ValN(V1, V3); + } + std::cout << "new method takes " << new_method_seconds << " seconds." << std::endl; + std::cout << "old method takes " << old_method_seconds << " seconds." << std::endl; + std::cout << "improvement " << old_method_seconds/new_method_seconds << "." << std::endl; +} \ No newline at end of file From d4ee1a85f393355a959f2933bfeb791d9e0e2f66 Mon Sep 17 00:00:00 2001 From: zhao lu Date: Mon, 5 Jul 2021 15:56:24 +0800 Subject: [PATCH 2/2] fix bug in IsNIdIn(const TInt&) in snap-core/cncom.h; test codes are added. --- snap-core/cncom.h | 2 +- test/Makefile | 3 +- test/test-TVec.cpp | 122 -------------------------------------------- test/test-cncom.cpp | 4 ++ 4 files changed, 6 insertions(+), 125 deletions(-) delete mode 100644 test/test-TVec.cpp diff --git a/snap-core/cncom.h b/snap-core/cncom.h index 5b1040597..cab395650 100644 --- a/snap-core/cncom.h +++ b/snap-core/cncom.h @@ -73,7 +73,7 @@ class TCnCom { TIntV& operator () () { return NIdV; } const TInt& GetVal(const int& NIdN) const { return operator[](NIdN); } void Sort(const bool& Asc = true) { NIdV.Sort(Asc); } - bool IsNIdIn(const int& NId) const { return NIdV.SearchBin(NId) != -1; } + bool IsNIdIn(const int& NId) const { return NIdV.IsIn(NId); } const TInt& GetRndNId() const { return NIdV[TInt::Rnd.GetUniDevInt(Len())]; } static void Dump(const TCnComV& CnComV, const TStr& Desc=TStr()); static void SaveTxt(const TCnComV& CnComV, const TStr& FNm, const TStr& Desc=TStr()); diff --git a/test/Makefile b/test/Makefile index d4d13bf58..0f8679f1e 100644 --- a/test/Makefile +++ b/test/Makefile @@ -47,8 +47,7 @@ TEST_SRCS = \ test-flow.cpp \ test-randwalk.cpp \ test-priority-queue.cpp \ - test-sim.cpp \ - test-TVec.cpp + test-sim.cpp TEST_OBJS = $(TEST_SRCS:.cpp=.o) diff --git a/test/test-TVec.cpp b/test/test-TVec.cpp deleted file mode 100644 index f3ed40656..000000000 --- a/test/test-TVec.cpp +++ /dev/null @@ -1,122 +0,0 @@ -#include - -#include -#include "Snap.h" -using namespace std; - -template -bool TestTVecEqual(const TVec& V1, const TVec& V2); - - -TEST(TVecTest, TIntVMergeV) { - -// Merge with unsorted normal TIntV - TIntV V1; V1.Add(1); V1.Add(2); V1.Add(3); V1.Add(5); - TIntV V2; V2.Add(7); V2.Add(4); V2.Add(5); V2.Add(2); - TIntV V3; V3.Add(1); V3.Add(2); V3.Add(3); V3.Add(4); V3.Add(5); V3.Add(7); - V1.AddVMerged(V2); - EXPECT_TRUE(TestTVecEqual(V1, V3)); - - // Merge with sorted normal TIntV - V1.Clr(); V1.Add(1); V1.Add(2); V1.Add(3); V1.Add(5); - V2.Clr(); V2.Add(0); V2.Add(2); V2.Add(4); V2.Add(6); - V3.Clr(); V3.Add(0); V3.Add(1); V3.Add(2); V3.Add(3); V3.Add(4); V3.Add(5); V3.Add(6); - V1.AddVMerged(V2); - EXPECT_TRUE(TestTVecEqual(V1, V3)); - - // Merge with more interleavings - V1.Clr(); V1.Add(1); V1.Add(3); V1.Add(5); V1.Add(9); V1.Add(10); - V2.Clr(); V2.Add(13); V2.Add(11); V2.Add(12); V2.Add(0); V2.Add(8); V2.Add(6); V2.Add(4); V2.Add(7); V2.Add(2); - V3.Clr(); - for (int i = 0; i < 14; i++) { - V3.Add(i); - } - V1.AddVMerged(V2); - EXPECT_TRUE(TestTVecEqual(V1, V3)); - - - // Merge with more interleavings and without overlapping - V1.Clr(); V1.Add(1); V1.Add(3); V1.Add(5); V1.Add(9); V1.Add(10); - V2.Clr(); V2.Add(13); V2.Add(11); V2.Add(12); V2.Add(0); V2.Add(8); V2.Add(6); V2.Add(4); V2.Add(7); V2.Add(2); - V2.Add(12); V2.Add(0); V2.Add(8); V2.Add(6); - V3.Clr(); - for (int i = 0; i < 14; i++) { - V3.Add(i); - } - V1.AddVMerged(V2); - EXPECT_TRUE(TestTVecEqual(V1, V3)); - - // Merge empty TIntV - V1.Clr(); V1.Add(1); V1.Add(2); V1.Add(3); - V2.Clr(); - V3 = V1; - V1.AddVMerged(V2); - EXPECT_TRUE(TestTVecEqual(V1, V3)); - - - // Empty TIntV merges with another normal TIntV - V2.AddVMerged(V1); - EXPECT_TRUE(TestTVecEqual(V2, V3)); - - // Merge the same TIntV - V2.AddVMerged(V3); - EXPECT_TRUE(TestTVecEqual(V2, V3)); - - // Merge two empty TIntV - V1.Clr(); - V2.Clr(); - V3.Clr(); - V1.AddVMerged(V3); - EXPECT_TRUE(TestTVecEqual(V2, V3)); -} - -template -bool TestTVecEqual(const TVec& V1, const TVec& V2){ - bool Result = true; - EXPECT_EQ(V1.Len(), V2.Len()); - Result &= V1.Len() == V2.Len(); - for (TInt ValN = 0; Result && ValN < V1.Len(); ValN++) { - EXPECT_EQ(V1[ValN], V2[ValN]); - Result = Result && (V1[ValN] == V2[ValN]); - } - return Result; -} - -#include -void TestNewMethodEfficiency(){ - const int Len1 = 10240; - const int Len2 = 10240; - const int Round = 1024; - TIntV V1; - TIntV V2; - double old_method_seconds = 0.0; - double new_method_seconds = 0.0; - for (int j = 0; j < Round; ++j) { - std::cout << "* " << j << endl; - V1.Clr(); V2.Clr(); - for (int k = 0; k < Len1; ++k) { - V1.Add(rand() % Len1); - } - for (int k = 0; k < Len2; ++k) { - V2.Add(rand() % Len1); - } - V1.Sort(); - TIntV V3 = V1; - auto start = chrono::system_clock::now(); - V1.AddVMerged(V2); - auto end = chrono::system_clock::now(); - chrono::duration seconds = end - start; - new_method_seconds += seconds.count(); - - start = chrono::system_clock::now(); - for (TInt ValN=0; ValN(V1, V3); - } - std::cout << "new method takes " << new_method_seconds << " seconds." << std::endl; - std::cout << "old method takes " << old_method_seconds << " seconds." << std::endl; - std::cout << "improvement " << old_method_seconds/new_method_seconds << "." << std::endl; -} \ No newline at end of file diff --git a/test/test-cncom.cpp b/test/test-cncom.cpp index c867c5989..f4b7fe6c0 100644 --- a/test/test-cncom.cpp +++ b/test/test-cncom.cpp @@ -113,6 +113,10 @@ TEST(CnComTest, UndirectedDisconnected) { EXPECT_TRUE(SCnComV[1].Len() == 2); EXPECT_TRUE(SCnComV[2].Len() == 2); + for(TInt ValN = 0; ValN < SCnComV[2].Len(); ValN++) { + EXPECT_TRUE(SCnComV[2].IsNIdIn(SCnComV[2].GetVal(ValN))); + } + double MxSccSz = GetMxSccSz(G); EXPECT_TRUE(MxSccSz > 0.86667 - EPSILON && MxSccSz < 0.86667 + EPSILON);