diff --git a/profiler_gui/arbitrary_value_inspector.cpp b/profiler_gui/arbitrary_value_inspector.cpp index 89e6620..a2e90e2 100644 --- a/profiler_gui/arbitrary_value_inspector.cpp +++ b/profiler_gui/arbitrary_value_inspector.cpp @@ -77,6 +77,7 @@ #include "arbitrary_value_inspector.h" #include "treeview_first_column_delegate.h" #include "globals.h" +#include "easy_complexity_calculator.h" ////////////////////////////////////////////////////////////////////////// diff --git a/profiler_gui/arbitrary_value_inspector.h b/profiler_gui/arbitrary_value_inspector.h index 36b5daa..6989595 100644 --- a/profiler_gui/arbitrary_value_inspector.h +++ b/profiler_gui/arbitrary_value_inspector.h @@ -95,18 +95,6 @@ enum class FilterType : uint8_t Median, }; -enum class ComplexityType : uint8_t -{ - Constant = 0, ///< O(1) - Logarithmic, ///< O(logN) - Linear, ///< O(N) - Quasilinear, ///< O(N*logN) - Quadratic, ///< O(N^2) - Cubic, ///< O(N^3) - Exponential, ///< O(2^N) - Factorial, ///< O(N!) -}; - enum class ChartPenStyle : uint8_t { Line = 0, diff --git a/profiler_gui/easy_complexity_calculator.h b/profiler_gui/easy_complexity_calculator.h new file mode 100644 index 0000000..51d1dc0 --- /dev/null +++ b/profiler_gui/easy_complexity_calculator.h @@ -0,0 +1,126 @@ +/** +Lightweight profiler library for c++ +Copyright(C) 2016-2018 Sergey Yagovtsev, Victor Zarubkin + +Licensed under either of + * MIT license (LICENSE.MIT or http://opensource.org/licenses/MIT) + * Apache License, Version 2.0, (LICENSE.APACHE or http://www.apache.org/licenses/LICENSE-2.0) +at your option. + +The MIT License + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished + to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + USE OR OTHER DEALINGS IN THE SOFTWARE. + + +The Apache License, Version 2.0 (the "License"); + You may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +**/ + +#ifndef EASY_COMPLEXITY_CALCULATOR_H +#define EASY_COMPLEXITY_CALCULATOR_H + +#include +#include +#include +#include +#include + +enum class ComplexityType : uint8_t +{ + Constant = 0, ///< O(1) + Logarithmic, ///< O(logN) + Linear, ///< O(N) + Quasilinear, ///< O(N*logN) + Quadratic, ///< O(N^2) + Cubic, ///< O(N^3) + Exponential, ///< O(2^N) + Factorial, ///< O(N!) + Unknown, ///< cannot estimate +}; + +template +TValue getAverage(const std::vector& derivatives) { + TValue result = std::accumulate(derivatives.begin(), derivatives.end(), TValue(0.0), [](TValue a, TValue b){ + if(std::isnormal(b)) { + return a + b; + } + return a; + }); + return result / TValue(derivatives.size()); +} + +template +std::vector calculateDerivatives(const std::map& input_array) { + std::vector result; + for(auto it = input_array.cbegin(), next_it = input_array.cbegin()++; next_it != input_array.cend();it = next_it, ++next_it) { + auto x0 = it->first; + auto x1 = next_it->first; + + auto y0 = it->second; + auto y1 = next_it->second; + + result.push_back((y1-y0)/(x1-x0)); + } + return result; +} + +template +std::map getLogarithmicChart(const std::map >& input) { + std::map result; + for(auto it: input) { + result[static_cast(std::log2(it.first))] = std::log2(getAverage(it.second)); + } + return result; +} + +template +ComplexityType estimateComplexity(const std::map >& input) { + auto average = getAverage(calculateDerivatives(getLogarithmicChart(input))); + + double estimate_angle = std::atan(double(average))*57.3; + if(estimate_angle < 1.0) { + return ComplexityType::Constant; + }else if (estimate_angle < 10.0) { + return ComplexityType::Logarithmic; + }else if (estimate_angle < 30.0) { + return ComplexityType::Linear; + }else if (estimate_angle < 50.0) { + return ComplexityType::Quasilinear; + }else if (estimate_angle < 65.0) { + return ComplexityType::Quadratic; + }else if (estimate_angle < 70.0) { + return ComplexityType::Cubic; + }else if (estimate_angle < 85.0) { + return ComplexityType::Exponential; + }else{ + return ComplexityType::Factorial; + } + + return ComplexityType::Unknown; +} + +#endif