表查找幾乎總是很好的表現。所以假設你已經認識到這是一個瓶頸,我會花時間來實現一個生成表的模板。不過,要衡量一下。性能是現代計算機上的一種奇怪的野獸。它可以走向一個永遠不會相信的方向。
我預計編譯時間表生成的時間確實很短。但事實證明,至少在舊版本2中,Visual C++ 2015並不滿意,因爲一個類中的constexpr std::array
。然而,最後,一個原始數組工作。
代碼,使用MinGW克++ 6.3.0和Visual C++ 2015更新2編譯:
#include <stddef.h> // size_t, ptrdiff_t
#include <utility> // std::(make_index_sequence,)
namespace my {
using std::make_index_sequence;
using std::index_sequence;
using Size = ptrdiff_t;
template< Size n, class Item >
using raw_array_of_ = Item[n];
template< class Item, size_t n >
constexpr
auto n_items_of(raw_array_of_<n, Item>&)
-> Size
{ return n; }
namespace impl {
constexpr
auto compile_time_pow_of_10(int const n)
-> double
{ return (n == 0? 1.0 : 10.0*compile_time_pow_of_10(n - 1)); }
template< size_t... indices >
struct Powers_of_10_
{
static constexpr size_t n = sizeof...(indices);
static constexpr raw_array_of_<n, double> table =
{
compile_time_pow_of_10(indices)...
};
constexpr
Powers_of_10_() {}
};
template< size_t... indices >
constexpr
raw_array_of_<Powers_of_10_<indices...>::n, double>
Powers_of_10_<indices...>::table;
template< size_t... indices, int n = sizeof...(indices) >
constexpr
auto power_of_10_table_helper(index_sequence<indices...>)
-> const raw_array_of_<n, double>&
{ return Powers_of_10_<indices...>::table; }
} // namespace impl
template< int n >
constexpr
auto power_of_10_table()
-> const raw_array_of_<n, double>&
{ return impl::power_of_10_table_helper(make_index_sequence<n>()); }
} // namespace my
#include <iostream>
using namespace std;
auto main()
-> int
{
int const n = 7;
constexpr auto& pow_10 = my::power_of_10_table<n>();
cout << n << " powers of 10:\n";
cout << fixed; cout.precision(0);
for(int i = 0; i < n; ++i)
{
cout << pow_10[i] << "\n";
}
}
模板代碼可能難以端口。即:Visual C++ 2015在上面的代碼中拒絕接受std::array
,因此需要重寫才能使用原始數組。由於通常過於冗長和神祕的編譯診斷,因此也難以維護。
甲相當快的積分功率函數可以通過表達功率作爲形式X(2 Ñ)的冪的乘積來定義。例如,X = X ⋅X ⋅X ,和X,即2,8這些更基本的權力,和32可以,通過重複平方計算x。這將指數中的線性乘法的次數減少到指數中的對數。
代碼:
#include <stddef.h> // size_t, ptrdiff_t
namespace my {
using Size = ptrdiff_t;
template< Size n, class Item >
using raw_array_of_ = Item[n];
namespace impl {
auto positive_integral_power_of(const double x, const int n)
{
double result = 1.0;
double power = x;
for(unsigned exp = n; ;)
{
if((exp & 1) != 0)
{
result *= power;
}
exp >>= 1;
if(exp == 0)
{
break;
}
power *= power;
}
return result;
}
} // namespace impl
auto integral_power_of(const double x, const int n)
-> double
{
return
n > 0?
impl::positive_integral_power_of(x, n) :
n < 0?
1.0/impl::positive_integral_power_of(x, -n) :
1.0;
}
} // namespace my
#include <iostream>
using namespace std;
auto main()
-> int
{
int const n = 7;
cout << n << " powers of 10:\n";
cout << fixed; cout.precision(0);
for(int i = 0; i < n; ++i)
{
cout << my::integral_power_of(10, i) << "\n";
}
}
過早的優化是所有罪惡的根源。你應該首先分析你的代碼,看看這是否是一個真正的瓶頸。 –
表查找幾乎總是很好的表現。所以*假設你已經認識到這是一個瓶頸*我會使用(預計會很短)時間來實現生成表的模板。然而,** ** **。性能是現代計算機上的一種奇怪的野獸。它可以走向一個永遠不會相信的方向。 –
唯一可以做的就是嘗試一下。這似乎是一個有效的事情,如果你知道你的函數被稱爲很多(如果它不是爲什麼),它肯定會有所幫助。而且它實際上會有相當狹窄的一組輸入,因此對於單元測試很簡單,一旦完成,您可以在其他項目中高度自信地重用它。 –