在C ++中,我可以使用memset初始化具有某些值的数组:
const int MAX = 1000000;
int is_prime[MAX]
memset(is_prime, 1, sizeof(is_prime))
memset所做的工作可以粗略地描述为用一些值填充数组,但是这样做确实非常快。
我可以这样做is_prime := make([]int, 1000000)
,但这将创建一个全为0的切片,以类似于我可以使用的方式new([1000000]int)
,但是没有任何东西将允许我创建全为1或任何其他非零元素的数组/切片。
当然,我可以在以后使用循环用值填充它,但是它的主要目的memset
是它比循环快得多。
那么Go程序员是否有一个memset
模拟(将数组初始化为一些非零值的快速方法)?
带有循环的最简单的解决方案如下所示:
func memsetLoop(a []int, v int) {
for i := range a {
a[i] = v
}
}
memset
标准库中没有支持,但是我们可以使用copy()
高度优化的内置函数。
copy()
我们可以手动设置第一个元素,然后使用copy()
;开始将已设置的部分复制到未设置的部分。每次已经设置的部分越来越大(两倍),因此迭代次数为log(n)
:
func memsetRepeat(a []int, v int) {
if len(a) == 0 {
return
}
a[0] = v
for bp := 1; bp < len(a); bp *= 2 {
copy(a[bp:], a[:bp])
}
}
此解决方案的灵感来自的实现bytes.Repeat()
。如果只想创建一个[]byte
填充相同值的新值,则可以使用该bytes.Repeat()
函数。您不能将它用于现有的切片或其他切片[]byte
,因为您可以使用呈现的切片memsetRepeat()
。
如果是小片,memsetRepeat()
可能会慢一些memsetLoop()
(但如果是小片,这并不重要,它将立即运行)。
由于使用fast copy()
,memsetRepeat()
如果元素数量增加,将会更快。
对这两个解决方案进行基准测试:
var a = make([]int, 1000) // Size will vary
func BenchmarkLoop(b *testing.B) {
for i := 0; i < b.N; i++ {
memsetLoop(a, 10)
}
}
func BenchmarkRepeat(b *testing.B) {
for i := 0; i < b.N; i++ {
memsetRepeat(a, 11)
}
}
100个元素: 快约1.15倍
BenchmarkLoop 20000000 81.6 ns/op
BenchmarkRepeat 20000000 71.0 ns/op
1,000个元素: 快约2.5倍
BenchmarkLoop 2000000 706 ns/op
BenchmarkRepeat 5000000 279 ns/op
10,000个元素: 快2倍
BenchmarkLoop 200000 7029 ns/op
BenchmarkRepeat 500000 3544 ns/op
100,000个元素: 快约1.5倍
BenchmarkLoop 20000 70671 ns/op
BenchmarkRepeat 30000 45213 ns/op
最高的性能提升约为3800-4000个元素, 速度提高了约3.2倍 。
Gos 自称为 “Armed Golang(加强版的 Go)”,定位是原生 go 命令的一个“加强版”解决方案。 据官方介绍可以使用 gos 代替 go: go get => gos getgo build => gos buildgo run => gos rungo ... => gos ... 因为 gos 兼容所有的 go 命令,并且还额外增加了搭载智能 GOPROXY 的 go mod/
gos-log 基于Go语言的轻量级高性能的大日志检索系统 开源地址 gos-log https://gitee.com/dianjiu/gos-log https://github.com/dianjiu/gos-log gos-log-vue https://gitee.com/dianjiu/gos-log-vue https://github.com/dianjiu/gos-log-vue
memset(将一段内存空间填入某值) 相关函数 bzero,swab 表头文件 #include<string.h> 定义函数 void * memset (void *s ,int c, size_t n); 函数说明 memset()会将参数s所指的内存区域前n个字节以参数c填入,然后返回指向s的指针。在编写程序时,若需要将某一数组作初始化,memset()会相当方便。 返回值 返回指向s的
memset 将一段内存空间填入某值 相关函数 bzero,swab 表头文件 #include<string.h> 定义函数 void *memset(void *s, int c, size_t n); 函数说明 memset()会将参数s所指的内存区域前n个字节以参数c填入,然后返回指向s的指针。在编写程序时,若需要将某一数组作初始化,memset()会相当方便。 返回值 返回指向s的指
问题内容: Java中是否有内置方法来查找任何数据类型的大小?有什么方法可以找到尺寸? 问题答案: 否。标准Java SE类库中没有这种方法。 设计者的观点是Java不需要它,因为该语言使应用程序1无需知道需要为原始值,对象或具有给定数量的元素的数组保留多少空间。 您可能会认为sizeof运算符对需要了解其数据结构占用多少空间的人很有用。但是,您还可以使用Java内存分析器简单,可靠地获得此信息以