性能暴力散列C++ Java
Performance brute force hashing C++ Java
我在C++和Java中为md5实现了蛮力器,并对为什么它们的效率不同有疑问。
数据和复杂度图(E^密码长度)与时间的关系图在这里:https://i.stack.imgur.com/NPxD3.png
密码是简单的"b"重复填充长度
在C++我使用了md5的实现:zedwood.com/article/cpp-md5-function
在Java中,我使用了这个站点上的第二个实现:http://www.asjava.com/core-java/java-md5-example/
在递归C++实现中,我的循环代码是在单独的类中完成的:
class bruteChar {
string charset;
char last_char;
string str;
string double_start;
char reverse_charset[256];
private:
string next(string s)
{
size_t length = s.size()-1;
if(length == 0)
{
if( s[0]==last_char)
return double_start;
return string(1, charset[reverse_charset[s[length]]+1]);
}
if(s[length] == last_char)
return next(s.substr(0,length))+charset[0];
else
return str.substr(0,length)+string(1, charset[reverse_charset[s[length]]+1]);
};
public:
void start (string chars)
{
charset = chars;
str=charset[0];
last_char=charset[charset.size()-1];
double_start=charset[0];
double_start+=charset[0];
for(size_t i = 0; i < charset.size(); ++i)
reverse_charset[charset[i]]=i;
reverse_charset[charset[charset.size()]]=0;
}
string next()
{
str=next(str);
return str;
}
};
在Java中,我使用了一个自定义类
public class picochar {
public static char[] charset = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray();
int num;
int mod;
picochar(int init, int mod)
{
num = init%mod;
}
picochar(char init, int mod)
{
for(int i = 0; i < mod; i++)
{
if(charset[i] == init)
num = i;
}
}
public char get()
{
return charset[num];
}
public boolean equals(char ch)
{
return (get() == ch);
}
public void increment()
{
num++;
}
}
和以下方法
public static String next(String s) {
int length = s.length();
picochar pc = new picochar(s.charAt(length - 1),mod);
if(pc.equals(picochar.charset[mod-1]))
return length > 1 ? next(s.substring(0, length - 1)) + 'a' : "aa";
pc.increment();
return s.substring(0, length - 1) + pc.get();
}
为什么Java在计算哈希方面比C++更有效?
我是否只是在 Java 中使用了一个高效的 MD5 实现,而在 C++ 中使用了一个糟糕的实现?
我认为C++会比Java快得多,因为Java必须通过JVM运行所有内容,而C是本机完成的。
然而,Java远远超过了C++解决方案。如果这仅仅是由于我在C++程序中编码不佳,我将如何解决这个问题?
编辑以删除不同的C++程序,现在两个解决方案都递归循环。
我做了一些时间,计算了在没有散列的情况下循环需要多长时间,这里的Java是C的两倍,这是@Dunes解释的。当重新编码为不使用substr()递归地使用,而是改变原始字符串时,C的速度大约是Java的两倍。
我做了一些测试,对哈希"hello"进行 1<<25 次哈希处理需要多长时间,并发现了一些奇怪的东西——Java 似乎"预热"得更快,虽然一开始速度较慢,但很快就会赶上 C 实现。
经过几秒钟的哈希处理后,C++会有类似的性能提升,但收益远不及Java
那么为什么Java预热更好呢?
看起来 c++ 实现如此缓慢的原因是因为您按值传递字符串。也就是说,每次使用字符串参数调用方法或返回字符串时,程序都必须创建整个字符串的全新副本。
然而,由于Java具有不可变的字符串,因此它可以传递同一字符串的不同视图。 String.substring
不会复制后备字符数组。相反,新的字符串对象只是跟踪与后备字符数组相关的起始索引和长度。当不明智地使用子字符串时,它可能会导致内存泄漏 - 只要原始的百万字符支持数组存在,一个 char 视图就会保持活动状态。
事实证明,我使用的是效率低下的 md5 实现。
以下是计算 227 个哈希所花费的时间与 openssl 所花费的时间
openssl v1
17.4911
openssl v2
14.9546
custom
291.201
- 在java中解决这段代码时面临循环中的问题
- 尝试用java代码编译和运行c++代码
- 在这种情况下,java对象是否可以调用本机函数
- 在java中读取c++字节的位字段
- 为什么C++对链表中的下一个节点使用指针,而像 C# 或 Java 这样的语言只使用类 Node 的名称?
- 使用已使用 java 编码的 openssl 解码数据
- SWIG Java 在使用 -DSWIGWORDSIZE64 时将int64_t转换为 jlong
- Android Java USB for native cpp
- 在由Sublime文本3编译后在cmd上显示Java程序输出
- C++ equivalent to Java Map getOrDefault?
- C++ 中的 Java 样式枚举
- 是否有技术原因阻止 Java 中的 final C++ 像 const 一样严格?
- 加密在 Windows、C++ 和 Java 中传输中的数据
- Java从C++回调到C++回调
- 在 c++ 中模拟输入并在 JAVA 中读取它?
- 用C++包装 Java 库 (JNI)
- 使用 TreeSet Java 对反转进行计数
- 验证openssl c++中的签名,这是由JAVA DSA签名的?
- 如何通过 JNI 将 C 字符串表情符号传递给 Java
- 如何从保存在 Java 中C++的字节数组中读取数字?