小编Lui*_*ins的帖子

当宏间接扩展自身时,了解 C 的预处理器的行为

当我在一个充满宏技巧和魔法的大项目中工作时,我偶然发现了一个错误,其中宏没有正确扩展。结果输出是“ EXPAND(0)”,但EXPAND被定义为“ #define EXPAND(X) X”,所以显然输出应该是“ 0”。

“没问题”,我心里想。“这可能是一些愚蠢的错误,这里有一些令人讨厌的宏,毕竟有很多地方会出错”。正如我所想的那样,我将行为不当的宏隔离到他们自己的项目中,大约 200 行,并开始使用 MWE 来查明问题。200 行变成了 150,然后又变成了 100,然后是 20、10……令我震惊的是,这是我最后的 MWE:

#define EXPAND(X) X
#define PARENTHESIS() ()
#define TEST() EXPAND(0)
   
EXPAND(TEST PARENTHESIS()) // EXPAND(0)
Run Code Online (Sandbox Code Playgroud)

4 行

雪上加霜的是,几乎对宏的任何修改都会使它们正常工作:

#define EXPAND(X) X
#define PARENTHESIS() ()
#define TEST() EXPAND(0)

// Manually replaced PARENTHESIS()
EXPAND(TEST ()) // 0
Run Code Online (Sandbox Code Playgroud)
#define EXPAND(X) X
#define PARENTHESIS() ()
#define TEST() EXPAND(0)

// Manually replaced TEST()
EXPAND(EXPAND(0)) // 0
Run Code Online (Sandbox Code Playgroud)
// Set EXPAND to 0 instead of X
#define …
Run Code Online (Sandbox Code Playgroud)

c macros c-preprocessor

77
推荐指数
3
解决办法
2370
查看次数

为什么 Pandas 操作没有到位?

Pandas 操作通常会创建原始数据帧的副本。正如 SO 上的一些答案指出的那样,即使在使用时inplace=True,许多操作仍然会创建一个副本来进行操作。

现在,如果我告诉我的同事,每次我想要申请+2一个列表时,我都会在做之前复制整个内容,我想我会被称为疯子。然而,这就是 Pandas 所做的。即使是简单的操作(例如追加)也会重新分配整个数据帧

必须在每个操作中重新分配和复制所有内容似乎是对任何数据进行操作的非常低效的方法。它还使得无法对特别大的数据帧进行操作,即使它们适合您的 RAM。

此外,这对于 Pandas 开发者或用户来说似乎不是问题,以至于有一个开放的问题 #16529 讨论完全删除该inplace参数,该问题得到了大部分积极的回应;有些从 1.0 开始就被弃用了。好像我错过了一些东西。那么,我错过了什么?

始终在操作上复制数据帧而不是尽可能就地执行它们有什么优点?

注意:我同意方法链接非常简洁,我一直使用它。然而,我觉得“因为我们可以方法链”并不是完整的答案,因为 Pandas 有时甚至在inplace=True方法中进行复制,而这些方法并不意味着被链接。因此,我正在寻找其他一些答案来了解为什么这是一个合理的默认值。

python in-place pandas

34
推荐指数
1
解决办法
2413
查看次数

如何查找 Rust 库的当前版本?

Cargo.toml文件要求我声明依赖项的版本,例如rand = "0.6".

我想使用该包rand_pcg,但不知道版本。我怎样才能找到它?

dependencies version rust rust-cargo

6
推荐指数
1
解决办法
5392
查看次数

获得矢量滤波器及其补集的惯用且有效的方法

假设我有一个向量,上面有一个过滤器,我想将它解构为两个向量:过滤后的向量及其补集。我看到有两种方法可以做到这一点。第一个是 for 循环:

let vct: Vec<u32> = vec![1, 3, 4, 7, 9, 10, 12];
let filter = |x| x % 3 == 0;

let mut filtered: Vec<u32> = Vec::new();
let mut complement: Vec<u32> = Vec::new();
for v in vct {
    if filter(v) {
        filtered.push(v);
    } else {
        complement.push(v);
    }
}

println!("{:?}", filtered);   //[3, 9, 12]
println!("{:?}", complement); //[1, 4, 7, 10]
Run Code Online (Sandbox Code Playgroud)

这看起来很有效,但不必要地冗长(并且给向量增加了不必要的可变性)。另一种是使用迭代器的简单方法:

let vct: Vec<u32> = vec![1, 3, 4, 7, 9, 10, 12];
let filter = |x:&&u32| *x % 3 …
Run Code Online (Sandbox Code Playgroud)

vector filter rust

3
推荐指数
1
解决办法
54
查看次数

x86_64 - 为什么用 rdtsc/rdtscp 给程序计时会给出不合理的大数字?

我正在尝试使用 rdtscp 为子例程计时。这是我的程序:

; Setting up time
rdtscp                      ; Getting time
push rax                    ; Saving timestamp

; for(r9=0; r9<LOOP_SIZE; r9++)
mov r9, 0
lup0:
call subr
inc r9
cmp r9, LOOP_SIZE
jnz lup0

; Calculating time taken
pop rbx                     ; Loading old time
rdtscp                      ; Getting time
sub rax, rbx                ; Calculating difference
Run Code Online (Sandbox Code Playgroud)

如果LOOP_SIZE足够小,我会得到一致和预期的结果。但是,当我让它足够大(大约 10^9)时,我会从 10^9 飙升到 10^20。

; Result with "LOOP_SIZE equ 100000000"
971597237
; Result with "LOOP_SIZE equ 1000000000"
18446744072281657066
Run Code Online (Sandbox Code Playgroud)

我用来显示数字的方法将它们显示为无符号,所以我想象显示的大数字实际上是一个负数并且发生了溢出。然而,971597237甚至还没有接近 64 位整数的限制,所以,假设问题是溢出,为什么会发生呢?

assembly x86-64 rdtsc

2
推荐指数
1
解决办法
84
查看次数