这个网站上已经存在很多性能问题,但是我发现几乎所有这些都是特定于问题且相当狭窄的问题.几乎所有人都重复这些建议,以避免过早优化.
我们假设:
我在这里寻找的是在一个关键算法中挤出最后几个百分点的策略和技巧,除此之外别无他法.
理想情况下,尝试使答案语言不可知,并在适用的情况下指出建议策略的任何缺点.
我将使用我自己的初步建议添加回复,并期待Stack Overflow社区可以想到的任何其他内容.
假设我们有一系列这样的整数:
const int size = 100000;
int array[size];
//set some items to 0 and other items to 1
Run Code Online (Sandbox Code Playgroud)
我想将所有值为1的项替换为另一个值,例如123456.这可以通过以下方式轻松实现:
for(int i = 0; i < size ; i++){
if(array[i] != 0)
array[i] = 123456;
}
Run Code Online (Sandbox Code Playgroud)
出于好奇,有没有更快的方法来做到这一点,通过某种x86技巧,或者这是处理器的最佳代码?
在性能方面(代数运算,查找,缓存等),C数组(可以作为C数组公开,或者cython.view.array[Cython数组],或上述两者的内存视图)和NumPy数组(在Cython中应该没有Python开销)
编辑:
我应该提一下,在NumPy数组中使用Cython进行静态类型化,dtypes是NumPy编译时数据类型(例如cdef np.int_t或者cdef np.float32_t),C语言中的类型是C等价物(cdef int_t和cdef float)
EDIT2:
以下是Cython Memoryview文档中的示例,以进一步说明我的问题:
from cython.view cimport array as cvarray
import numpy as np
# Memoryview on a NumPy array
narr = np.arange(27, dtype=np.dtype("i")).reshape((3, 3, 3))
cdef int [:, :, :] narr_view = narr
# Memoryview on a C array
cdef int carr[3][3][3]
cdef int [:, :, :] carr_view = carr
# Memoryview on a Cython …Run Code Online (Sandbox Code Playgroud) 在使用指针时,我编写了以下代码,
int main()
{
int a[]={10,20,30,40,50};
int i;
for(i=0;i<5;i++)
{
printf("\n%d",*a);
a++;
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
现在根据我的理解,数组名称本身是c中的地址,根据我的知识,完成的指针算法是正确的.但是,当我尝试运行代码时,它给了我"Lvalue Required"错误.
那么出现Lvalue所需错误的确切原因是什么呢?因为在此之前我也遇到过这种错误的情况.其次,为什么指针的算术在这种情况下不合法呢?
有些人说:"任何可以通过数组下标实现的操作也可以通过指针来完成.指针版本通常会更快".
我怀疑上面的结果,所以我做了以下测试:
在下面的文章中,我们不关心编译器优化.关于编译器优化如何影响指针和数组之间的效率,请注意:效率:数组与指针
(Visual Studio 2010,调试模式,无优化)
#include <windows.h>
#include <stdio.h>
int main()
{
int a[] = {10,20,30};
int* ap = a;
long counter;
int start_time, end_time;
int index;
start_time = GetTickCount();
for (counter = 1000000000L; counter>0; counter--)
{
*(ap+1) = 100;
}
end_time = GetTickCount();
printf("10 billion times of *ap = %d\n", end_time-start_time);
start_time = GetTickCount();
for (counter = 1000000000L; counter>0; counter--)
{
a[1] = 101;
}
end_time = GetTickCount();
printf("10 billion times of a[0] = %d\n", end_time-start_time);
return …Run Code Online (Sandbox Code Playgroud) 我正在使用元素数组,其中许多元素相互引用,我假设在这种情况下使用指针更有效.但在某些情况下,我需要知道我有指针的元素的索引.例如,我有p = &a[i],我需要知道的价值i.据我了解,i可以通过计算p - a.但是这种操作固有地涉及分割,这是昂贵的,而从数组索引计算地址涉及乘法并且更快.
所以我的问题是,在需要索引的情况下是否使用指针进行交叉引用甚至是值得的?
我正在用C++编写一个练习,并且我编写了一个在我看来有效的代码,但我不确定,因为我还是初学者,有人可以检查它并告诉我它们是否是相同与否.
解决方案代码:
Point *PointArray::get( const int pos) {
return pos >= 0 && pos < size ? points + pos : NULL;
}
Run Code Online (Sandbox Code Playgroud)
我的代码是:
Point* PointArray::get (const int position) {
return &(data[position]);
}
Run Code Online (Sandbox Code Playgroud)
我意识到在我的代码中我必须检查条件以检查是否返回空指针,但除此之外,我的版本是否与 points + pos
points&data是Point类的数组,我命名为我的数据,名为它的解决方案.
编辑:
我添加条件后的代码:
Point* PointArray::get (const int position) {
return ((position >= 0 && position < size) ? &(data[position]) : NULL);
}
Run Code Online (Sandbox Code Playgroud)