正如我在上一篇文章中写的那样,我对c#世界还是一个新手,所以我写了一个小基准来比较Dictionary,Hashtable,SortedList和SortedDictionary.该测试运行8000次迭代,从50到100000个元素.我测试了添加新元素,搜索元素并循环遍历一些元素.结果就像我预期的那样,除了SortedDictionary的结果,这让我感到很困惑......所有结果都很慢.所以我错过了关于排序字典概念的一些内容.我已经问了谷歌,但我发现的所有其他人都得到了相同的测试结果.根据他们的测试实施略有不同.我的问题再次出现:为什么SortedDicrionary比其他所有人慢得多?
我最近一直在研究基准测试,我一直对记录程序数据等感兴趣.我有兴趣知道我们是否可以实现自己的内存使用代码并在我们的程序中有效地实现我们自己的时间消耗代码.我知道如何检查代码运行所需的时间:
public static void main(String[]args){
long start = System.currentTimeMillis();
// code
System.out.println(System.currentTimeMillis() - start);
}
Run Code Online (Sandbox Code Playgroud)
我还研究了Robust Java基准测试,第1部分:问题,本教程非常全面.显示的负面影响System.currentTimeMillis();.然后教程建议我们使用System.nanoTime();(使其更准确?).
我还研究了使用Java确定内存使用情况以获取内存使用情况.该网站显示了如何实施它.提供的代码看起来无穷无尽,因为此人正在呼叫
long L = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
在此之后,他打电话给System.gc();(4*4)= 16次.然后再次重复该过程.这不也占用记忆吗?
那么在结论中,是否可以在java程序中实现高效的基准测试代码?
几个小时前我回答了另一个Stack Overflow问题,结果非常令人惊讶.答案可以在这里找到.答案是/部分错误,但我觉得专注于字节添加.
严格来说,它实际上是字节到长的添加.
这是我一直使用的基准代码:
public class ByteAdditionBenchmark {
private void start() {
int[] sizes = {
700_000,
1_000,
10_000,
25_000,
50_000,
100_000,
200_000,
300_000,
400_000,
500_000,
600_000,
700_000,
};
for (int size : sizes) {
List<byte[]> arrays = createByteArrays(size);
//Warmup
arrays.forEach(this::byteArrayCheck);
benchmark(arrays, this::byteArrayCheck, "byteArrayCheck");
}
}
private void benchmark(final List<byte[]> arrays, final Consumer<byte[]> method, final String name) {
long start = System.nanoTime();
arrays.forEach(method);
long end = System.nanoTime();
double nanosecondsPerIteration = (end - start) * 1d / arrays.size();
System.out.println("Benchmark: …Run Code Online (Sandbox Code Playgroud) 我注意到Rust的测试有一个测量执行时间的基准模式ns/iter,但我找不到测量内存使用情况的方法.
我该如何实施这样的基准?让我们假设目前我只关心堆内存(虽然堆栈使用也肯定会很有趣).
编辑:我发现这个问题要求完全相同的事情.
我的笔记本电脑配备Intel Core 2 Duo 2.4GHz CPU和2x4Gb DDR3模块1066MHz.
我希望这个内存可以以1067 MiB/sec的速度运行,并且只要有两个通道,最大速度为2134 MiB/sec(如果OS内存调度程序允许的话).
我做了一个小Java应用程序来测试:
private static final int size = 256 * 1024 * 1024; // 256 Mb
private static final byte[] storage = new byte[size];
private static final int s = 1024; // 1Kb
private static final int duration = 10; // 10sec
public static void main(String[] args) {
long start = System.currentTimeMillis();
Random rnd = new Random();
byte[] buf1 = new byte[s];
rnd.nextBytes(buf1);
long count = 0;
while (System.currentTimeMillis() …Run Code Online (Sandbox Code Playgroud) 如何衡量用Java编写的代码的速度?
我计划开发软件,使用所有目前可用的AI和ML算法解决数独,并将时间与简单的蛮力方法进行比较.我需要测量每种算法的时间,我想问一下最好的方法是什么?非常重要的是,无论CPU电源/内存如何,程序都必须适用于任何机器.
谢谢.
Makefile当我这样做时,有没有办法回应递归的每个目标所花费的(系统,用户,真实)时间make all?
我想以更细粒度的方式对项目的编译进行基准测试time make all.理想情况下,它会回显执行目标的树,每个树都有在其所有依赖项中花费的时间.如果它可以使用-j(并行制作)也会很棒.顺便说一下,我Makefile是非递归的(不会make为每个主要目标产生另一个实例).
谢谢!
我在文档中读取了String类,它eql?是一个严格的相等运算符,没有类型转换,并且==是一个等于运算符,它尝试将其参数的第二个转换为String,并且此方法的C源代码确认:
该eql?源代码如下:
static VALUE
rb_str_eql(VALUE str1, VALUE str2)
{
if (str1 == str2) return Qtrue;
if (TYPE(str2) != T_STRING) return Qfalse;
return str_eql(str1, str2);
}
Run Code Online (Sandbox Code Playgroud)
该==源代码如下:
VALUE
rb_str_equal(VALUE str1, VALUE str2)
{
if (str1 == str2) return Qtrue;
if (TYPE(str2) != T_STRING) {
if (!rb_respond_to(str2, rb_intern("to_str"))) {
return Qfalse;
}
return rb_equal(str2, str1);
}
return str_eql(str1, str2);
}
Run Code Online (Sandbox Code Playgroud)
但是当我尝试对这些方法进行基准测试时,我感到惊讶的==是,速度比eql?高达20%快!我的基准代码是:
require "benchmark"
RUN_COUNT = 100000000
first_string = "Woooooha"
second_string …Run Code Online (Sandbox Code Playgroud) 我决定要对特定函数进行基准测试,所以我天真地编写如下代码:
#include <ctime>
#include <iostream>
int SlowCalculation(int input) { ... }
int main() {
std::cout << "Benchmark running..." << std::endl;
std::clock_t start = std::clock();
int answer = SlowCalculation(42);
std::clock_t stop = std::clock();
double delta = (stop - start) * 1.0 / CLOCKS_PER_SEC;
std::cout << "Benchmark took " << delta << " seconds, and the answer was "
<< answer << '.' << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
一位同事指出,我应该声明start和stop变量volatile以避免代码重新排序.他建议优化器可以,例如,有效地重新排序代码,如下所示:
std::clock_t start = std::clock();
std::clock_t stop = …Run Code Online (Sandbox Code Playgroud) 在Chandler Carruth的CppCon 2015演讲中,他介绍了两种神奇的功能,可以在没有任何额外性能损失的情况下击败优化器.
作为参考,这里是函数(使用GNU样式的内联汇编):
void escape(void* p)
{
asm volatile("" : : "g"(p) : "memory");
}
void clobber()
{
asm volatile("" : : : "memory");
}
Run Code Online (Sandbox Code Playgroud)
它适用于任何支持GNU样式内联汇编的编译器(GCC,Clang,Intel编译器,可能还有其他编译器).但是,他提到它在MSVC中不起作用.
检查Google Benchmark的实现,似乎他们使用重新解释转换为a volatile const char&并将其传递给隐藏在非gcc/clang编译器上的不同翻译单元中的函数.
template <class Tp>
inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp const& value) {
internal::UseCharPointer(&reinterpret_cast<char const volatile&>(value));
}
// some other translation unit
void UseCharPointer(char const volatile*) {}
Run Code Online (Sandbox Code Playgroud)
但是,我对此有两个顾虑:
MSVC中是否有与GNU样式的汇编函数相同的低级别?或者这是MSVC上最好的?
benchmarking ×10
java ×4
memory ×2
performance ×2
c# ×1
c++ ×1
dictionary ×1
equality ×1
gnu-make ×1
hardware ×1
makefile ×1
profiling ×1
ruby ×1
rust ×1
string ×1
visual-c++ ×1
volatile ×1