小编Art*_*oul的帖子

从给定索引数组的Python列表中提取子列表的最快方法

我有l任何类型的对象的大型Python列表,还有另一个指向 list 中某些元素的整数索引的大型列表i(甚至NumPy数组)l

问题是创建另一个列表的最快(最有效)的方法是什么,l2该列表包含 的元素l以及来自 的索引i

最简单的方法是进行列表理解:

l2 = [l[si] for si in i]
# Use np.nditer(i) instead of i, for NumPy array case
Run Code Online (Sandbox Code Playgroud)

但这是最快的方法吗?

列表理解是一个 Python 循环,因此对于大型列表可能会很慢,也许标准库中有一些内置的 Python 方法可以高效编写C来实现此任务?或者也许NumPy有这样的方法通过 numpy 数组索引 Python 列表?

也许标准 python 库中有一些简单快速的函数可以对 NumPy 的np.take执行相同的操作,如下面的假想代码所示:

import listtools
l2 = listtools.take(l, indexes)
Run Code Online (Sandbox Code Playgroud)

python arrays numpy list

5
推荐指数
2
解决办法
1028
查看次数

NumPy - 最快的非加密抗碰撞哈希

我正在为NumPy寻找最好的64-bit(或至少是32-bit)具有下一个属性的哈希函数

  1. 它针对 numpy 进行了矢量化,这意味着它应该具有散列任何 ND numpy 数组的所有元素的函数。
  2. 它可以应用于任何可散列的 numpy 的dtype. 为此,这种散列能够仅处理原始字节块就足够了。
  3. 它非常非常快,就像xxhash一样。特别是对于许多小输入,例如 32、64 位数字或短 np.str_ 的巨大数组,它应该很快,但也应该处理其他 dtype。
  4. 它应该是抗碰撞的。我可能只使用部分位,所以散列中的任意数量的位也应该是抗碰撞的。
  5. 它可能是(也可能不是)非加密的,这意味着如果它有时可以反转就可以了,比如xxhash.
  6. 它应该产生64-bit整数或更大的输出,但如果是,32-bit那么仍然可以,尽管不是那么可取。如果可能的话,最好选择生成 32、64、128 位大小的散列。
  7. 它本身应该在内部将 numpy 数组转换为字节以使散列速度更快,或者至少可能在 numpy 中已经有这样的转换函数,可以将任何流行的 dtype 的整个 ND 数组转换为可变的字节序列,如果有人会告诉我这个很好.

xxhash如果它有numpy数组矢量化,我会使用上面链接提到的。但是现在它只是单个对象,它的绑定函数每次调用只接受一个字节块,产生一个整数输出。并且 xxhash 每次调用小(4、8 个字节)输入时只使用几个 CPU 周期,因此可能在大数组上执行纯 Python 循环来为每个数字调用 xxhash 效率非常低。

我需要它用于不同的事情,一个是概率存在过滤器(或集合),即我需要设计这样的结构(集合),N如果请求的元素可能在集合中或不是。为此,我想使用较低的散列位将输入分布到K存储桶中,并且每个存储桶还存储一些(可调整的)较高位的数量,以增加正确答案的概率。另一个应用是布隆过滤器。我需要这个集合在添加和请求时非常快,并且在内存中尽可能紧凑,并处理非常多的元素。

如果没有现有的好的解决方案,那么也许我还可以改进xxhash库并向作者的存储库创建拉取请求。

python arrays hash performance numpy

5
推荐指数
1
解决办法
290
查看次数

Numba - 编译时间常数优化

我有使用Numba进行JIT编辑的人工示例代码:

import numba
@numba.njit
def f(x, c):
    for i in range(3):
        if c == 0:
            x += 1
        elif c == 1:
            x *= 2
        else:
            assert False
    return x
print(f(3, 0), f(3, 1))
Run Code Online (Sandbox Code Playgroud)

c如果是来自小的最终整数值集的某个常数,例如,如何优化它0 <= c <= 3

不允许将if有关条件c移出循环,因为这将是一个明显的优化。因为它是一个人为的示例,所以在实际示例中,循环可能会很大,并且仅更改主体内部的 1-2 行即可重复循环两次是负担不起的。

基本上我想让c编译时保持不变。与C++一样,可以将编译时常量作为模板参数,并执行与此相关的所有代码优化。

所以我想告诉 Numba 参数c0c1等是编译时常量,应该以这样的方式处理:每当使用不同的cNumba 值调用函数时,都应该创建和编译一个单独的函数实例并进行必要的优化,就像C++生成一样当传递新的模板参数集时,模板化函数的每次实例化。

换句话说,这些常量的可能值c应该包含在函数的签名中,据我了解,Numba 会为每个不同的签名生成单独的函数代码,就像 C++ 模板一样。

另一种需要优化的情况是,whenc不是函数的参数,而是循环开始之前某些复杂表达式计算的结果。在这种情况下,结果c …

python optimization templates compile-time-constant numba

5
推荐指数
0
解决办法
313
查看次数

如何在 C++ 中检查声明的标识符?

我想在代码的某个点检查是否x声明了某个标识符,我该怎么做?

我需要对不同类型的标识符进行这种检查 - 变量、枚举常量、函数、类型、宏等。但首先我想至少检查变量和函数。

我需要这样的检查(例如虚数declared(x)),以便下一个代码适用于 int 变量的情况x

if constexpr(declared(x)) {
    int y = x + 1;
} else {
    std::cout << "Variable 'x' not declared!" << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

对于原因宏的情况,我可以使用#ifdef x,但是如何对变量/函数进行相同的检查?

对于全局非 lambda 函数的情况,我根据重载函数解析计算出了下一个代码,但它需要使用基于辅助宏的全局定义(可以进一步简化吗?):

在线尝试一下!

#include <iostream>
#include <type_traits>

#define declared_func_helper(x, ...) \
    struct NotDeclared; \
    template <typename ... Args> \
    NotDeclared x(Args ...); \
    template <typename ... Args> \
    inline constexpr bool declared_func_##x(Args && ... args) { \
        return !std::is_same_v<decltype(x(args...)), NotDeclared>; \ …
Run Code Online (Sandbox Code Playgroud)

c++ reflection variables declaration function

5
推荐指数
1
解决办法
800
查看次数

N下所有素数的优化求和

eular 项目中有第 10 个问题。

问题是求所有不大于N的素数之和。

我对这个问题的解决方案是:

int solve(int n){

    bool check[n+1];
    for(int i=0;i<=n;i++){
        check[i]=true;
    }

    for(int i=2;i*i<=n;i++){
        if(check[i]){
            for(int j=i*i;j<=n;j+=i){
                check[j]=false;
            }
        }
    }

    int sum=0;
    for(int i=2;i<=n;i++){
        if(check[i]){
            sum+=i;
        }
    }
    return sum;
}
Run Code Online (Sandbox Code Playgroud)

但问题仍然没有得到足够的优化,因为我收到了“由于超时而终止”的消息。

我怎样才能更好地优化这段代码。

限制条件是:

1<= T <= 10^4 ( T 是测试用例的数量 )

1<=N<=10^6

你可以在这里自己尝试一下

c++ algorithm primes sieve-of-eratosthenes

5
推荐指数
1
解决办法
653
查看次数

在 C++ 中获取可以容纳给定量位的最小整数类型

如果我有编译时间常数,num_bits如何获得可以容纳这么多位的最小整数类型?

我当然可以这样做:

在线尝试一下!

#include <cstdint>
#include <type_traits>
std::size_t constexpr num_bits = 19;
using T =
    std::conditional_t<num_bits <=  8, uint8_t,
    std::conditional_t<num_bits <= 16, uint16_t,
    std::conditional_t<num_bits <= 32, uint32_t,
    std::conditional_t<num_bits <= 64, uint64_t,
        void>>>>;
Run Code Online (Sandbox Code Playgroud)

但也许标准库中存在一些现成的元函数来实现这个目标?

我创建这个问题只是为了专门从标准库中找出单个元函数。但是,如果除了我提出的上述解决方案之外,您还有其他好的建议如何解决此任务,那么也请发布此类解决方案......


更新。正如评论中所建议的,uint_leastX_t应该使用而不是uintX_t在上面的代码中的任何地方使用,因为uintX_t在某些平台上可能不存在,但uint_leastX_t始终存在。

c++ c++20 c++23

5
推荐指数
1
解决办法
890
查看次数

在 MSVC C++ 中强制内联 lambda

下一个代码在 CLang/GCC 中编译,并成功内联 lambda:

在线试试吧!

#include <iostream>

int main() {
    int x = 0;
    auto f = [&]() __attribute__((always_inline)) {
        ++x;
    };
    f();
    std::cout << x;
}
Run Code Online (Sandbox Code Playgroud)

但是与__forceinline最新的 MSVC(2019 v16.8.3)中的类似代码无法编译,尽管已宣布在 v16.7 中实现

在线试试吧!

#include <iostream>

int main() {
    int x = 0;
    auto f = [&]() __forceinline {
        ++x;
    };
    f();
    std::cout << x;
}
Run Code Online (Sandbox Code Playgroud)

抛出编译错误0305.cpp(5): error C3260: 'type': skipping unexpected token(s) before lambda body

它真的还没有实现还是我用__forceinline错了地方?有没有其他方法可以在 MSVC 中强制内联 lambda?

在所有流行的编译器(例如 CLang/GCC/MSVC)中是否有任何方法不编译代码(并抛出编译错误),以防在某些地方使用给定的 lambda …

c++ lambda inline visual-c++ visual-studio-2019

4
推荐指数
1
解决办法
259
查看次数

如何在 CLang C++ 下编译/使用头单元模块?

文档中说 CLang 中的模块支持是部分的。我在最近发布的 LLVM 12.0 中在 Windows 64 位下使用 CLang。

我成功地设法使用了常规模块(您通过 导入import modulename;)。

但我还没有设法创建和使用头单元模块,那些你通过import "header.hpp";. 你能建议如何用例子做到这一点吗?

为了尝试标题单元,我创建了下一个玩具文件:

你好.hpp

#include <vector>
Run Code Online (Sandbox Code Playgroud)

使用.cpp

import "hello.hpp";

int main() {
    std::vector<int> v(123);
}
Run Code Online (Sandbox Code Playgroud)

然后我成功(我希望)将头单元编译hello.hpp成 PCM 文件:

clang++ -std=c++20 -Xclang -emit-header-module -I. hello.hpp -o hello.pcm
Run Code Online (Sandbox Code Playgroud)

命令运行没有错误并产生hello.pcm. 如果您在没有-o标志的情况下运行上面的命令,hello.hpp.gch则会创建文件 。

然后我尝试编译use.cpp,但没有成功,不知何故它无法识别我的头单元和/或找不到相应的hello.pcm. 我想我错过了一些特殊的标志,这些标志表明编译器是头单元。使用了下一个命令:

clang++ -std=c++20 -fprebuilt-module-path=. -fmodule-file=hello.hpp=hello.pcm -I. use.cpp
Run Code Online (Sandbox Code Playgroud)

这给了编译错误:

use.cpp:1:8: error: header file "hello.hpp" (aka './hello.hpp') cannot be imported …
Run Code Online (Sandbox Code Playgroud)

c++ clang c++20 c++-modules

4
推荐指数
1
解决办法
301
查看次数

有效地移位或大位向量

我有一个大的内存数组作为一些指针uint64_t * arr(加上大小),它代表普通位。我需要非常有效(性能最高/速度最快)将这些位从 0 向右移动一定量到 63。

通过移动整个数组,我的意思是不移动每个元素(如a[i] <<= Shift),而是将其作为单个大位向量移动。换句话说,对于每个中间位置i(第一个和最后一个元素除外),我可以在循环中执行以下操作:

dst[i] = w | (src[i] << Shift);
w = src[i] >> (64 - Shift);
Run Code Online (Sandbox Code Playgroud)

其中w是一些临时变量,保存前一个数组元素的右移值。

上面这个解决方案简单明了。但我需要更高效的东西,因为我有千兆字节的数据。

理想情况下,为此使用一些 SIMD 指令,因此我正在寻找专家的 SIMD 建议。我需要为所有四种类型的流行指令集实现移位代码 - SSE-SSE4.2 / AVX / AVX-2 / AVX-512。

但据我所知,例如 SSE2 只存在_mm_slli_si128()内在/指令,它仅移位 8 的倍数(换句话说,字节移位)。我需要按任意位大小进行移位,而不仅仅是字节移位。

如果没有 SIMD,我也可以通过 using 指令一次移位 128 位shld reg, reg, reg,这允许进行 128 位移位。它在 MSVC 中作为内部__shiftleft128()实现,并生成可以在此处看到的汇编代码。

顺便说一句,我需要所有 MSVC/GCC/CLang 的解决方案。

另外,在单循环迭代中,我可以在顺序操作中移位 4 或 8 个字,这将使用 …

c++ performance sse simd avx

4
推荐指数
1
解决办法
1214
查看次数

C++ Boost 多精度整数 uint256_t 的 sizeof 大于 32 字节

众所周知,C++ 内置类型 uint32_t、int32_t、uint64_t、int64_t 甚至 GCC/CLang 内置类型 __int128 和 unsigned __int128 的 sizeof 都恰好等于位宽除以 8。

但是,如果打印 Boost 的 sizeof boost::multiprecision::uint256_tuint512_t则 uint256_t 会得到 48 字节而不是 32 字节,uint512_t 会得到 80 字节而不是 64 字节。两种类型的 sizeof 都比预期多 16 个字节。请参阅此处的演示

但 sizeofboost::multiprecision::uint128_t恰好给出了预期的 16 个字节。

Boost 的所有整数的基类似乎cpp_int_base有几个字段:

data_type m_data;
unsigned  m_limbs;
bool      m_sign, m_internal, m_alias;
Run Code Online (Sandbox Code Playgroud)

只有 m_data 字段包含整数位,而其他字段则额外提供了 16 个不必要的 sizeof 字节。

我的问题是否可以以某种方式调整 Boost 多精度整数,使其仅包含数据位而不包含其他内容?

换句话说,它保持符号(如果是有符号整数)与Intel CPU将其保留在int64_t中相同,基本上最高位是符号位,其余位以符号补码形式编码。因此 Boost 整数的编码与默认的 intel uint64_t、int64_t 相同。

如果您查看模板的签名,cpp_int_base您会看到:

template <unsigned …
Run Code Online (Sandbox Code Playgroud)

c++ boost x86-64 bigint boost-multiprecision

4
推荐指数
1
解决办法
596
查看次数