本人是刚从C++转过来的newbie,今天在LeetCode刷了道题,分别用C++和Rust以相同思路实现,得到的结果根本不是一个数量级的,求大佬帮我分析一下原因,不胜感激。
平均数据如下:
语言 耗时(ms) 内存(MB)
C++ 300 177
Rust 35 4.2
题目链接:2766. 重新放置石块
C++实现
class Solution {
public:
vector<int> relocateMarbles(vector<int>& nums, vector<int>& moveFrom, vector<int>& moveTo) {
std::unordered_set<int> unique_set;
for (auto &item : nums) {
unique_set.insert(item);
}
for (size_t i = 0; i < moveFrom.size(); i++) {
unique_set.erase(moveFrom[i]);
unique_set.insert(moveTo[i]);
}
vector<int> result;
for (auto &item : unique_set)
result.push_back(item);
sort(result.begin(), result.end());
return result;
}
};
Rust实现
use std::collections::HashSet;
impl Solution {
pub fn relocate_marbles(nums: Vec<i32>, move_from: Vec<i32>, move_to: Vec<i32>) -> Vec<i32> {
let mut unique_set:HashSet<i32> = nums.into_iter().collect();
for i in 0..move_from.len() {
unique_set.remove(&move_from[i]);
unique_set.insert(move_to[i]);
}
let mut result = Vec::new();
for iter in unique_set {
result.push(iter);
}
result.sort();
result
}
}
评论区
写评论leecode 的问题,Java在里面都比c++快
我也碰到过debug比release编译更久的,导致我很长时间都不用debug编译。后来想想,有可能是release模式在词法分析的时候把一些unused/deadcode和无输出的代码块给直接优化掉了,但debug模式则会全量解析编译。我不懂啊,我猜的。
--
👇
dreamtale90: rust这个优化有点魔性,我自己写那个测试,输入也是10w数据,编译时间O2要两分多,O3才十七八秒,但程序执行时间差不多。。。
rust这个优化有点魔性,我自己写那个测试,输入也是10w数据,编译时间O2要两分多,O3才十七八秒,但程序执行时间差不多。。。
--
👇
lithbitren: 歪个楼,之前看那个一个啥文章,说放弃三年rust游戏开发,好像说实践里o1用得比较多,综测性能和o3差不多,但编译时间大大缩短。
--
👇
TinusgragLin: > leetcode测试不一定开o3吧,我不太懂啊。
看了一下,完全不开优化的话,我这边 test-rust 会慢一点,o1,o2 的结果和 o3 差不多。
嗯,后来我自己也在本地测了,应该就是LeetCode环境/优化的事。
--
👇
TinusgragLin: 我简单地做了一下测试,用代码随机产生三个长度为 10 万的数串(输入到文件
input0
,input1
,input2
),作为输入:C++ 测试程序:
Rust 测试程序:
makefile:
运行
make bench
的结果:歪个楼,之前看那个一个啥文章,说放弃三年rust游戏开发,好像说实践里o1用得比较多,综测性能和o3差不多,但编译时间大大缩短。
--
👇
TinusgragLin: > leetcode测试不一定开o3吧,我不太懂啊。
看了一下,完全不开优化的话,我这边 test-rust 会慢一点,o1,o2 的结果和 o3 差不多。
我把 cpp 这边
std::unordered_set
换成abseil::flat_hash_set
速度就上来了,我估计再换个 sort 实现两边就相差无几了。看了一下,完全不开优化的话,我这边 test-rust 会慢一点,o1,o2 的结果和 o3 差不多。
leetcode测试不一定开o3吧,我不太懂啊。
我简单地做了一下测试,用代码随机产生三个长度为 10 万的数串(输入到文件
input0
,input1
,input2
),作为输入:C++ 测试程序:
Rust 测试程序:
makefile:
运行
make bench
的结果:java在leetcode测试的时候可能是已经启动预热好再加载脚本的,而且每个用户提交的脚本执行应该没有系统级的隔离,jit加速有时候比cpp快不出奇。最慢的应该是python,前几年刷题的时候,遇到过一道hard题,相同的最优算法只有python过不了,其他其他js,ts,go,rs,cpp,java都能轻松过,后来投诉了,然后官方改了py的判定时间才能ac。
leetcode 的问题,你用java写 可能得到的数据更快
哦,好的。
--
👇
WANG-lp: 很有可能是sort算法不一样导致性能不一样,rust的sort对某些场景有特殊优化
这还真不知道,看来想搞清楚还得本地测。
--
👇
facefaceless: 不用纠结这个,力扣对c++有负优化,甚至会出现比java慢的情况
对于C++肯定是有历史包袱问题的
--
👇
Dangerise: 也许是Rust有后发优势,标准库算法普遍优于STL?
嗯好
--
👇
lithbitren: 一点编码风格小别扭,rust里既然vec转hashset用了iter写进一行,反过来hashset转vec也应该iter啊
嗯,有时间自己本地测一测。
--
👇
wangbyby: 不太清楚leetcode机器资源情况,可能得自己本地验证一下。
1.准备相同测试数据分别喂给cpp,rust程序 2.cpp编译器用clang开O2/O3,rust用release 3.多跑几轮取均值
不用纠结这个,力扣对c++有负优化,甚至会出现比java慢的情况
一点编码风格小别扭,rust里既然vec转hashset用了iter写进一行,反过来hashset转vec也应该iter啊
很有可能是sort算法不一样导致性能不一样,rust的sort对某些场景有特殊优化
不太清楚leetcode机器资源情况,可能得自己本地验证一下。
1.准备相同测试数据分别喂给cpp,rust程序 2.cpp编译器用clang开O2/O3,rust用release 3.多跑几轮取均值