Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Code here:
- Results below:
- #include <string>
- #include <list>
- #include <utility>
- #define PTR
- // This is purposefully badly packed
- struct ExpensiveType
- {
- int heapDataSize;
- bool trueOrFalse1;
- double loadsOfData[1024];
- char* heapData;
- bool trueOrFalse2;
- std::string iHaveACtor;
- std::list<std::string> expensive;
- };
- // The way I would classically do it - I don't use non-const refs in
- // functions like this since I often forget that they can modify the
- // object if I don't look explicitly at the function signature
- void DoSomething(ExpensiveType* inOut)
- {
- std::swap(inOut->trueOrFalse1, inOut->trueOrFalse2);
- for (auto& i : inOut->loadsOfData)
- i /= 2.0;
- inOut->iHaveACtor += " argh this should probably require the string to allocate more memory";
- if (inOut->heapData != nullptr)
- {
- char* temp = new char[inOut->heapDataSize];
- std::copy(inOut->heapData, inOut->heapData+inOut->heapDataSize, temp);
- delete [] inOut->heapData;
- inOut->heapData = temp;
- }
- auto tempFront = inOut->expensive.front();
- auto tempBack = inOut->expensive.back();
- inOut->expensive.pop_front();
- inOut->expensive.pop_back();
- inOut->expensive.push_front(tempBack);
- inOut->expensive.push_back(tempFront);
- }
- // Using pass-by-value
- ExpensiveType DoSomethingElse(ExpensiveType in)
- {
- std::swap(in.trueOrFalse1, in.trueOrFalse2);
- for (auto& i : in.loadsOfData)
- i /= 2.0;
- in.iHaveACtor += " argh this should probably require the string to allocate more memory";
- if (in.heapData != nullptr)
- {
- char* temp = new char[in.heapDataSize];
- std::copy(in.heapData, in.heapData+in.heapDataSize, temp);
- delete [] in.heapData;
- in.heapData = temp;
- }
- auto tempFront = in.expensive.front();
- auto tempBack = in.expensive.back();
- in.expensive.pop_front();
- in.expensive.pop_back();
- in.expensive.push_front(tempBack);
- in.expensive.push_back(tempFront);
- return in;
- }
- int main(void)
- {
- ExpensiveType data;
- data.trueOrFalse1 = true;
- data.trueOrFalse2 = false;
- for (int i = 0; i < 1024; ++i)
- {
- data.loadsOfData[i] = i;
- data.expensive.push_back(std::to_string(i));
- }
- data.heapDataSize = 10;
- data.heapData = new char[data.heapDataSize];
- for (int i = 0; i < data.heapDataSize; ++i)
- data.heapData[i] = data.heapDataSize - i;
- for (int i = 0; i < 10e3; ++i)
- {
- #ifdef PTR
- DoSomething(&data);
- #else
- data = DoSomethingElse(data);
- #endif
- // try and make sure the loop doesn't get optimised out
- data.trueOrFalse1 = !data.trueOrFalse1;
- }
- #ifdef PTR
- DoSomething(&data);
- #else
- data = DoSomethingElse(data);
- #endif
- return 0;
- }
- # Unoptimised Clang 3.7 (-O0)
- ## Value
- $ for i in {1..10}; do time bin/test; done
- real 0m1.259s
- user 0m1.110s
- sys 0m0.143s
- real 0m1.260s
- user 0m1.138s
- sys 0m0.116s
- real 0m1.251s
- user 0m1.163s
- sys 0m0.088s
- real 0m1.252s
- user 0m1.119s
- sys 0m0.128s
- real 0m1.258s
- user 0m1.178s
- sys 0m0.080s
- real 0m1.260s
- user 0m1.103s
- sys 0m0.152s
- real 0m1.254s
- user 0m1.125s
- sys 0m0.124s
- real 0m1.254s
- user 0m1.149s
- sys 0m0.099s
- real 0m1.254s
- user 0m1.145s
- sys 0m0.104s
- real 0m1.258s
- user 0m1.140s
- sys 0m0.112s
- ## Pointer
- $ for i in {1..10}; do time bin/test; done
- real 0m0.033s
- user 0m0.030s
- sys 0m0.004s
- real 0m0.033s
- user 0m0.033s
- sys 0m0.000s
- real 0m0.033s
- user 0m0.033s
- sys 0m0.000s
- real 0m0.033s
- user 0m0.029s
- sys 0m0.004s
- real 0m0.033s
- user 0m0.033s
- sys 0m0.000s
- real 0m0.034s
- user 0m0.034s
- sys 0m0.000s
- real 0m0.033s
- user 0m0.033s
- sys 0m0.005s
- real 0m0.033s
- user 0m0.033s
- sys 0m0.000s
- real 0m0.033s
- user 0m0.033s
- sys 0m0.000s
- real 0m0.035s
- user 0m0.034s
- sys 0m0.000s
- # Clang optimised (-O2 -flto -march=native -mfpmath=sse)
- # Value
- $ for i in {1..10}; do time bin/test; done
- real 0m0.801s
- user 0m0.665s
- sys 0m0.136s
- real 0m0.800s
- user 0m0.671s
- sys 0m0.128s
- real 0m0.796s
- user 0m0.659s
- sys 0m0.136s
- real 0m0.795s
- user 0m0.698s
- sys 0m0.096s
- real 0m0.792s
- user 0m0.663s
- sys 0m0.129s
- real 0m0.792s
- user 0m0.662s
- sys 0m0.128s
- real 0m0.800s
- user 0m0.680s
- sys 0m0.120s
- real 0m0.797s
- user 0m0.660s
- sys 0m0.133s
- real 0m0.805s
- user 0m0.676s
- sys 0m0.128s
- real 0m0.794s
- user 0m0.678s
- sys 0m0.116s
- ## Pointer
- $ for i in {1..10}; do time bin/test; done
- real 0m0.005s
- user 0m0.000s
- sys 0m0.005s
- real 0m0.005s
- user 0m0.005s
- sys 0m0.000s
- real 0m0.005s
- user 0m0.000s
- sys 0m0.005s
- real 0m0.005s
- user 0m0.003s
- sys 0m0.003s
- real 0m0.005s
- user 0m0.005s
- sys 0m0.000s
- real 0m0.006s
- user 0m0.006s
- sys 0m0.000s
- real 0m0.005s
- user 0m0.005s
- sys 0m0.000s
- real 0m0.005s
- user 0m0.005s
- sys 0m0.000s
- real 0m0.005s
- user 0m0.005s
- sys 0m0.000s
- real 0m0.005s
- user 0m0.003s
- sys 0m0.003s
- # GCC 4.8 Optimised (same as switches as clang)
- ## Value
- $ for i in {1..10}; do time bin/test; done
- real 0m0.781s
- user 0m0.673s
- sys 0m0.104s
- real 0m0.784s
- user 0m0.669s
- sys 0m0.111s
- real 0m0.779s
- user 0m0.638s
- sys 0m0.140s
- real 0m0.777s
- user 0m0.684s
- sys 0m0.092s
- real 0m0.787s
- user 0m0.657s
- sys 0m0.128s
- real 0m0.778s
- user 0m0.651s
- sys 0m0.124s
- real 0m0.779s
- user 0m0.670s
- sys 0m0.108s
- real 0m0.778s
- user 0m0.642s
- sys 0m0.136s
- real 0m0.774s
- user 0m0.677s
- sys 0m0.096s
- real 0m0.777s
- user 0m0.680s
- sys 0m0.096s
- ## Pointer
- $ for i in {1..10}; do time bin/test; done
- real 0m0.010s
- user 0m0.010s
- sys 0m0.000s
- real 0m0.010s
- user 0m0.010s
- sys 0m0.000s
- real 0m0.011s
- user 0m0.011s
- sys 0m0.000s
- real 0m0.009s
- user 0m0.006s
- sys 0m0.003s
- real 0m0.010s
- user 0m0.009s
- sys 0m0.000s
- real 0m0.010s
- user 0m0.010s
- sys 0m0.000s
- real 0m0.010s
- user 0m0.010s
- sys 0m0.000s
- real 0m0.010s
- user 0m0.009s
- sys 0m0.000s
- real 0m0.010s
- user 0m0.009s
- sys 0m0.000s
- real 0m0.011s
- user 0m0.010s
- sys 0m0.000s
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement