我正在尝试使用最小的额外内存开销实现一个与BST一样好的跳过列表,目前即使不考虑任何内存限制,我的SkipList实现的性能也远远不是一个非常天真的平衡BST实现 - 所以说,手工制作的BTS :) -
作为参考,我使用了William Pugh PUG89的原始论文以及我在Sedgewick -13.5-的C中算法中发现的实现.我的代码是一个递归实现,这是插入和查找操作的线索:
sl_node* create_node()
{
short lvl {1};
while((dist2(en)<p)&&(lvl<max_level))
++lvl;
return new sl_node(lvl);
}
void insert_impl(sl_node* cur_node,
sl_node* new_node,
short lvl)
{
if(cur_node->next_node[lvl]==nullptr || cur_node->next_node[lvl]->value > new_node->value){
if(lvl<new_node->lvl){
new_node->next_node[lvl] = cur_node->next_node[lvl];
cur_node->next_node[lvl] = new_node;
}
if(lvl==0) return;
insert_impl(cur_node,new_node,lvl-1);
return;
}
insert_impl(cur_node->next_node[lvl],new_node,lvl);
}
sl_node* insert(long p_val)
{
sl_node* new_node = create_node();
new_node->value = p_val;
insert_impl(head, new_node,max_level-1);
return new_node;
}
Run Code Online (Sandbox Code Playgroud)
这是查找操作的代码:
sl_node* find_impl(sl_node* cur_node,
long p_val,
int lvl)
{
if(cur_node==nullptr) return nullptr;
if(cur_node->value==p_val) return …
Run Code Online (Sandbox Code Playgroud) TL; DR:第一个循环在Haswell CPU上运行速度快〜18%.为什么?循环来自gcc -O0
使用ptr++
vs的(未优化的)循环++ptr
,但问题是为什么生成的asm表现不同,而不是关于如何写出更好的C.
假设我们有两个循环:
movl $0, -48(%ebp) //Loop counter set to 0
movl $_data, -12(%ebp) //Pointer to the data array
movl %eax, -96(%ebp)
movl %edx, -92(%ebp)
jmp L21
L22:
// ptr++
movl -12(%ebp), %eax //Get the current address
leal 4(%eax), %edx //Calculate the next address
movl %edx, -12(%ebp) //Store the new (next) address
// rest of the loop is the same as the other
movl -48(%ebp), %edx //Get the loop counter to …
Run Code Online (Sandbox Code Playgroud) 我发现那些类似的问题Lambda表达式作为类模板参数和如何使用lambda表达式作为模板参数?,但即使有可用的答案我也不明白为什么以下代码不起作用(g ++ 4.8.2和g ++ - 4.9):
auto GoLess = [](int a,int b) -> bool
{
return a < b;
};
template<typename Order>
struct foo
{
int val;
bool operator<(const foo& other)
{
return Order(val, other.val);
}
};
typedef foo<decltype(GoLess)> foo_t;
int main()
{
foo_t a,b;
bool r = a < b;
}
Run Code Online (Sandbox Code Playgroud)
编译器输出是:
test.cpp: In instantiation of ‘bool foo<Order>::operator<(const foo<Order>&) [with Order = <lambda(int, int)>]’:
test.cpp:26:15: required from here
test.cpp:17:30: error: no matching function for call …
Run Code Online (Sandbox Code Playgroud) 给出以下示例:
struct test
{
const char* data;
const int number;
};
struct test* foo()
{
static struct test t = {
"this is some data",
69
};
return &t;
}
Run Code Online (Sandbox Code Playgroud)
对线程的调用是foo
安全的吗?换句话说,该结构是否仅以线程安全的方式初始化一次?如果用 C 或 C++ 编译它有什么区别吗?
我对这个小例子有点困惑:
using mytype = std::vector<std::string>;
template<typename T>
void test(T item)
{
throw std::runtime_error(typeid(item).name());
}
template<>
void test(std::vector<std::string>&& vec)
{
std::cout<<"Ok."<<std::endl;
}
int main()
{
mytype stuff;
test(std::forward<mytype>(stuff));
}
Run Code Online (Sandbox Code Playgroud)
我希望在这里为调用选择专门的模板,但事实并非如此,删除&&
将使这种情况发生(并且参数移至vec
)..
为什么test
没有使用专门用于右值参数的版本?
我的问题非常简单,我想以同样的方式使用lambda,我可以使用functor作为'比较器',让我解释一下.我有两个大的结构,它们都有自己的实现operator<
,并且我还有一个useless
类(这只是这个问题上下文中的类的名称),它使用了两个结构,一切看起来像这样:
struct be_less
{
//A lot of stuff
int val;
be_less(int p_v):val(p_v){}
bool operator<(const be_less& p_other) const
{
return val < p_other.val;
}
};
struct be_more
{
//A lot of stuff
int val;
be_more(int p_v):val(p_v){}
bool operator<(const be_more& p_other) const
{
return val > p_other.val;
}
};
class useless
{
priority_queue<be_less> less_q;
priority_queue<be_more> more_q;
public:
useless(const vector<int>& p_data)
{
for(auto elem:p_data)
{
less_q.emplace(elem);
more_q.emplace(elem);
}
}
};
Run Code Online (Sandbox Code Playgroud)
我想删除两个结构中的重复,最简单的想法是使结构成为模板并提供两个函数来进行比较工作:
template<typename Comp>
struct be_all
{
//Lot of stuff, …
Run Code Online (Sandbox Code Playgroud) 我对归并排序算法做了一个非常简单的实现,然后我将其用于 CUDA,只需很少的实现更改,算法代码如下:
//Merge for mergesort
__device__ void merge(int* aux,int* data,int l,int m,int r)
{
int i,j,k;
for(i=m+1;i>l;i--){
aux[i-1]=data[i-1];
}
//Copy in reverse order the second subarray
for(j=m;j<r;j++){
aux[r+m-j]=data[j+1];
}
//Merge
for(k=l;k<=r;k++){
if(aux[j]<aux[i] || i==(m+1))
data[k]=aux[j--];
else
data[k]=aux[i++];
}
}
//What this code do is performing a local merge
//of the array
__global__
void basic_merge(int* aux, int* data,int n)
{
int i = blockIdx.x*blockDim.x + threadIdx.x;
int tn = n / (blockDim.x*gridDim.x);
int l = i * tn;
int r = …
Run Code Online (Sandbox Code Playgroud) 假设我们在全局命名空间中声明了以下lambda:
auto Less = [](int a,int b) -> bool
{
return a < b;
}
Run Code Online (Sandbox Code Playgroud)
以下代码使用了这个lambda:
template<typename T>
struct foo
{
foo(int v){}
bool operator<(const foo<T>&) const
{
return T(1,2);
}
};
int main()
{
typedef foo<decltype(Less)> be_less;
priority_queue<be_less> data;
}
Run Code Online (Sandbox Code Playgroud)
如您所见,我将其Less
用作结构的模板参数foo
.使用g ++ 4.9.2,此代码无法编译:
test1.cpp:13:21: error: no matching function for call to '<lambda(int, int)>::__lambda0(int, int)'
return T(1,2);
^
test1.cpp:13:21: note: candidates are:
test1.cpp:17:14: note: constexpr<lambda(int, int)>::<lambda>(const<lambda(int, int)>&)
auto Less = [](int a,int b) -> bool
^ …
Run Code Online (Sandbox Code Playgroud) 我只有一个简单的问题,请查看此代码:
template < typename A >
void foo( A a )
{ cout<<"1\n"; };
template< >
void foo<float>( float a )
{ cout<<"2\n"; }
void foo( float a )
{ cout<<"3\n"; }
int main()
{
foo<float>( 1.0f );
}
Run Code Online (Sandbox Code Playgroud)
用g ++ 4.7.2编译当然可以,但我不清楚的是为什么输出是"2"而不是"3".
据我记得,非模板函数应始终优先用于模板,因此为什么称为专用foo?
谢谢
有一些我对for语句没有理解的东西,在下面的代码中请集中注意力??? 评论:
void user_interface::execute_a_command( const string& cmd, command cmd_table[] )
{
LOG("user_interface::execute_a_command(): Executing \"",cmd,"\"");
bool command_executed = false;
//Exist any operation for this command?
command* elem = &cmd_table[ 0 ]; //???
for( int i = 0 ; cmd_table[ i ].function != nullptr ; i++, elem = &cmd_table[ i ] )
{
if( cmd == elem->name )
{
//Call the function
(this->*(elem->function))();
command_executed = true;
break;
}
}
Run Code Online (Sandbox Code Playgroud)
好吧,这段代码编译得很好,没有特别的警告.但是,如果我将'elem'的声明和初始化放在'for'语句中,如下所示:
for( int i = 0 , command* elem = &cmd_table[ 0 ] …
Run Code Online (Sandbox Code Playgroud) 我有些不清楚的地方希望引起您的注意,请检查这些代码片段:
template< typename DerivedClass >
class construction_management
{
city* this_city;
public:
construction_management()
{
this_city = static_cast< city* >(this);
}
~construction_management();
};
Run Code Online (Sandbox Code Playgroud)
我故意删除了所有不必要的代码,请查看构造函数,它将“this”指针静态转换为“city”类型,其定义如下:
class city : public construction_management< city >
{
public:
public:
city( const string& name, const string& owner );
};
Run Code Online (Sandbox Code Playgroud)
该类故意为空,因为我认为它所包含的内容与此处无关。希望我无法 100% 理解这里发生的事情,g++ 4.7.2 在编译阶段不打印警告或错误,每当我使用“this_city”指针时,我都可以访问 city 的所有公共成员,对象本身看起来是一致的,因为所有变量都已正确初始化并且始终包含有效数据。
我想知道的是,如果我将 Construction_management 定义为普通的非模板类,为什么此代码不起作用?由于尝试从 const 转换为指向城市的非 const 指针,转换失败,为什么?
这是错误打印:
game.hpp: In constructor 'city_manager::construction_management::construction_management()':
game.hpp:164:41: error: invalid static_cast from type 'city_manager::construction_management* const' to type 'city_manager::city*'
Run Code Online (Sandbox Code Playgroud)
如果 Construction_management 是一个模板,为什么还要工作呢?这是一种CRTP吗?
谢谢你们。
c++ ×10
templates ×4
c++11 ×3
lambda ×3
algorithm ×2
performance ×2
assembly ×1
c ×1
crtp ×1
cuda ×1
declaration ×1
for-loop ×1
gpgpu ×1
inheritance ×1
loops ×1
mergesort ×1
skip-lists ×1
sorting ×1
static ×1
static-cast ×1
x86 ×1