论坛首页 Java企业应用论坛

论String操作时间复杂度

浏览 17740 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2013-05-10  
须等待 写道
编译器优化之后两段代码应该是一样的执行效果吧???


for循环里面,编译器不会优化。
0 请登录后投票
   发表时间:2013-05-10  
teasp 写道
须等待 写道
编译器优化之后两段代码应该是一样的执行效果吧???


for循环里面,编译器不会优化。

抛开楼主的问题不谈,弱弱的问个不相干的问题

拷贝一个数组,用循环和用System.arrayCopy或C的memcpy整段内存拷贝的时间复杂度是不是一样
0 请登录后投票
   发表时间:2013-05-10  
ticmy 写道
teasp 写道
须等待 写道
编译器优化之后两段代码应该是一样的执行效果吧???


for循环里面,编译器不会优化。

抛开楼主的问题不谈,弱弱的问个不相干的问题

拷贝一个数组,用循环和用System.arrayCopy或C的memcpy整段内存拷贝的时间复杂度是不是一样


映像中System.arrayCopy用的就是本地优化过的方法
0 请登录后投票
   发表时间:2013-05-10  
须等待 写道
ticmy 写道
teasp 写道
须等待 写道
编译器优化之后两段代码应该是一样的执行效果吧???


for循环里面,编译器不会优化。

抛开楼主的问题不谈,弱弱的问个不相干的问题

拷贝一个数组,用循环和用System.arrayCopy或C的memcpy整段内存拷贝的时间复杂度是不是一样


映像中System.arrayCopy用的就是本地优化过的方法


时间复杂度是多少
0 请登录后投票
   发表时间:2013-05-11  
ticmy 写道
须等待 写道
ticmy 写道
teasp 写道
须等待 写道
编译器优化之后两段代码应该是一样的执行效果吧???


for循环里面,编译器不会优化。

抛开楼主的问题不谈,弱弱的问个不相干的问题

拷贝一个数组,用循环和用System.arrayCopy或C的memcpy整段内存拷贝的时间复杂度是不是一样


映像中System.arrayCopy用的就是本地优化过的方法


时间复杂度是多少


我的直觉是O(1)。
0 请登录后投票
   发表时间:2013-05-11  
teasp 写道
ticmy 写道
须等待 写道
ticmy 写道
teasp 写道
须等待 写道
编译器优化之后两段代码应该是一样的执行效果吧???


for循环里面,编译器不会优化。

抛开楼主的问题不谈,弱弱的问个不相干的问题

拷贝一个数组,用循环和用System.arrayCopy或C的memcpy整段内存拷贝的时间复杂度是不是一样


映像中System.arrayCopy用的就是本地优化过的方法


时间复杂度是多少


我的直觉是O(1)。

O(1)的意思是,拷贝1个字节和拷贝1M字节所用时间是一样的,即,算法所用时间与数据量无关。
没有这么神奇的数组拷贝方法吧?

楼主两个算法,其中一个无论如何优化,每次循环应该都触发一次数组拷贝。
每次拷贝的时间复杂度为O(N),而每次循环N都加1。
另一个算法由于使用了StringBuilder,如果不考虑自动扩展,就没有数组拷贝,但是至少还是要遍历一遍源字符串,所以时间复杂度是O(N),即算法所用时间直接与源串长度相关。
0 请登录后投票
   发表时间:2013-05-11  
mike.liu 写道
teasp 写道
ticmy 写道
须等待 写道
ticmy 写道
teasp 写道
须等待 写道
编译器优化之后两段代码应该是一样的执行效果吧???


for循环里面,编译器不会优化。

抛开楼主的问题不谈,弱弱的问个不相干的问题

拷贝一个数组,用循环和用System.arrayCopy或C的memcpy整段内存拷贝的时间复杂度是不是一样


映像中System.arrayCopy用的就是本地优化过的方法


时间复杂度是多少


我的直觉是O(1)。

O(1)的意思是,拷贝1个字节和拷贝1M字节所用时间是一样的,即,算法所用时间与数据量无关。
没有这么神奇的数组拷贝方法吧?

楼主两个算法,其中一个无论如何优化,每次循环应该都触发一次数组拷贝。
每次拷贝的时间复杂度为O(N),而每次循环N都加1。
另一个算法由于使用了StringBuilder,如果不考虑自动扩展,就没有数组拷贝,但是至少还是要遍历一遍源字符串,所以时间复杂度是O(N),即算法所用时间直接与源串长度相关。

搜索了一番,都说memcpy快到极致,拷贝1个字节和拷贝大批数据是一样的,“远低于printf等屏幕显示类函数,就算是空循环体的for循环再编译后也会产生若干行,比memcpy要慢”
0 请登录后投票
   发表时间:2013-05-11   最后修改:2013-05-11
ticmy 写道
mike.liu 写道
teasp 写道
ticmy 写道
须等待 写道
ticmy 写道
teasp 写道
须等待 写道
编译器优化之后两段代码应该是一样的执行效果吧???


for循环里面,编译器不会优化。

抛开楼主的问题不谈,弱弱的问个不相干的问题

拷贝一个数组,用循环和用System.arrayCopy或C的memcpy整段内存拷贝的时间复杂度是不是一样


映像中System.arrayCopy用的就是本地优化过的方法


时间复杂度是多少


我的直觉是O(1)。

O(1)的意思是,拷贝1个字节和拷贝1M字节所用时间是一样的,即,算法所用时间与数据量无关。
没有这么神奇的数组拷贝方法吧?

楼主两个算法,其中一个无论如何优化,每次循环应该都触发一次数组拷贝。
每次拷贝的时间复杂度为O(N),而每次循环N都加1。
另一个算法由于使用了StringBuilder,如果不考虑自动扩展,就没有数组拷贝,但是至少还是要遍历一遍源字符串,所以时间复杂度是O(N),即算法所用时间直接与源串长度相关。

搜索了一番,都说memcpy快到极致,拷贝1个字节和拷贝大批数据是一样的,“远低于printf等屏幕显示类函数,就算是空循环体的for循环再编译后也会产生若干行,比memcpy要慢”


以前研究过VC里面的实现,是把char*转换为int*来做memcmp或memcpy的,这样在32位系统里面有优势,可以做到一个机器指令就比较或者拷贝4个字节。但即使是这样,时间复杂度也是0(N/4),还是受制于要拷贝的数据量。这个可以通过测试得到验证。

至于说“memcpy快到极致,拷贝1个字节和拷贝大批数据是一样的”,这个说法我还是第一次听到。虽然知道有些CPU有原生的数组操作指令(即数组的拷贝、比较等操作只需要一条机器指令),但实际上还是需要多次访问内存或L1/L2缓存,如果数据量超过L1/L2缓存,就会涉及多个指令周期的问题。基于这个原理,我还是无法理解这种说法。

不过我始终坚信IT里面是没有魔法的。


楼主的问题里面,涉及到Java的运行时优化。由于String是final,优化做到极致,是可以达到等于第二种的性能的。但是在不优化的情况下,第个方法里面生成新的String时,必然涉及到数组拷贝操作。
0 请登录后投票
   发表时间:2013-05-11   最后修改:2013-05-11
mike.liu 写道
ticmy 写道
mike.liu 写道
teasp 写道
ticmy 写道
须等待 写道
ticmy 写道
teasp 写道
须等待 写道
编译器优化之后两段代码应该是一样的执行效果吧???


for循环里面,编译器不会优化。

抛开楼主的问题不谈,弱弱的问个不相干的问题

拷贝一个数组,用循环和用System.arrayCopy或C的memcpy整段内存拷贝的时间复杂度是不是一样


映像中System.arrayCopy用的就是本地优化过的方法


时间复杂度是多少


我的直觉是O(1)。

O(1)的意思是,拷贝1个字节和拷贝1M字节所用时间是一样的,即,算法所用时间与数据量无关。
没有这么神奇的数组拷贝方法吧?

楼主两个算法,其中一个无论如何优化,每次循环应该都触发一次数组拷贝。
每次拷贝的时间复杂度为O(N),而每次循环N都加1。
另一个算法由于使用了StringBuilder,如果不考虑自动扩展,就没有数组拷贝,但是至少还是要遍历一遍源字符串,所以时间复杂度是O(N),即算法所用时间直接与源串长度相关。

搜索了一番,都说memcpy快到极致,拷贝1个字节和拷贝大批数据是一样的,“远低于printf等屏幕显示类函数,就算是空循环体的for循环再编译后也会产生若干行,比memcpy要慢”



以前研究过VC里面的实现,是把char*转换为int*来做memcmp或memcpy的,这样在32位系统里面有优势,可以做到一个机器指令就比较或者拷贝4个字节。但即使是这样,时间复杂度也是0(N/4),还是受制于要拷贝的数据量。这个可以通过测试得到验证。

至于说“memcpy快到极致,拷贝1个字节和拷贝大批数据是一样的”,这个说法我还是第一次听到。虽然知道有些CPU有原生的数组操作指令(即数组的拷贝、比较等操作只需要一条机器指令),但实际上还是需要多次访问内存或L1/L2缓存,如果数据量超过L1/L2缓存,就会涉及多个指令周期的问题。基于这个原理,我还是无法理解这种说法。

不过我始终坚信IT里面是没有魔法的。


楼主的问题里面,涉及到Java的运行时优化。由于String是final,优化做到极致,是可以达到等于第二种的性能的。但是在不优化的情况下,第个方法里面生成新的String时,必然涉及到数组拷贝操作。


O(1)的意思显然不是复制1字节和1M字节所用的时间都一样。为了方便你理解,HashMap里面只有1条数据,和有1M条数据时查找的时间是一样的吗?但是它是O(1)的。
0 请登录后投票
   发表时间:2013-05-11   最后修改:2013-05-11
teasp 写道
mike.liu 写道
ticmy 写道
mike.liu 写道
teasp 写道
ticmy 写道
须等待 写道
ticmy 写道
teasp 写道
须等待 写道
编译器优化之后两段代码应该是一样的执行效果吧???


for循环里面,编译器不会优化。

抛开楼主的问题不谈,弱弱的问个不相干的问题

拷贝一个数组,用循环和用System.arrayCopy或C的memcpy整段内存拷贝的时间复杂度是不是一样


映像中System.arrayCopy用的就是本地优化过的方法


时间复杂度是多少


我的直觉是O(1)。

O(1)的意思是,拷贝1个字节和拷贝1M字节所用时间是一样的,即,算法所用时间与数据量无关。
没有这么神奇的数组拷贝方法吧?

楼主两个算法,其中一个无论如何优化,每次循环应该都触发一次数组拷贝。
每次拷贝的时间复杂度为O(N),而每次循环N都加1。
另一个算法由于使用了StringBuilder,如果不考虑自动扩展,就没有数组拷贝,但是至少还是要遍历一遍源字符串,所以时间复杂度是O(N),即算法所用时间直接与源串长度相关。

搜索了一番,都说memcpy快到极致,拷贝1个字节和拷贝大批数据是一样的,“远低于printf等屏幕显示类函数,就算是空循环体的for循环再编译后也会产生若干行,比memcpy要慢”



O(1)的意思显然不是复制1字节和1M字节所用的时间都一样。为了方便你理解,HashMap里面只有1条数据,和有1M条数据时查找的时间是一样的吗?但是它是O(1)的。

以前研究过VC里面的实现,是把char*转换为int*来做memcmp或memcpy的,这样在32位系统里面有优势,可以做到一个机器指令就比较或者拷贝4个字节。但即使是这样,时间复杂度也是0(N/4),还是受制于要拷贝的数据量。这个可以通过测试得到验证。

至于说“memcpy快到极致,拷贝1个字节和拷贝大批数据是一样的”,这个说法我还是第一次听到。虽然知道有些CPU有原生的数组操作指令(即数组的拷贝、比较等操作只需要一条机器指令),但实际上还是需要多次访问内存或L1/L2缓存,如果数据量超过L1/L2缓存,就会涉及多个指令周期的问题。基于这个原理,我还是无法理解这种说法。

不过我始终坚信IT里面是没有魔法的。


楼主的问题里面,涉及到Java的运行时优化。由于String是final,优化做到极致,是可以达到等于第二种的性能的。但是在不优化的情况下,第个方法里面生成新的String时,必然涉及到数组拷贝操作。



HashMap只是在理想情况下(散列得非常好)时间复杂度是O(1)。它只能接近O(1)时间复杂度,当遇到冲突时,肯定时间复杂度要大于0(1)。真正为O(1)的,有数组的下标访问。有10个元素的数组用下标访问花1秒的话,1G数组用下标访问任意元素,其时间复杂度还是1秒。链表(LinkList)用下标访问时间复杂度就是O(N),获取元素的时间与链表中元素个数,以及下标都有关系。HashMap只是在理想情况下接近O(1)。

另外我理解O(1)时间复杂度的意思就是该算法与输入的数据量无关,是固定值。数组的下标访问能够满足这个。HashMap理想情况下接近这个。O(N)的意思是算法的时间与输入数据量成正比关系。
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics