【发布时间】:2017-08-16 19:29:28
【问题描述】:
出于纯粹的教育目的,我创建了一个base58 包。它将使用bitcoin base58 symbol chart 对uint64 进行编码/解码,例如:
b58 := Encode(100) // return 2j
num := Decode("2j") // return 100
在创建第一个测试时,我使用this:
func TestEncode(t *testing.T) {
var i uint64
for i = 0; i <= (1<<64 - 1); i++ {
b58 := Encode(i)
num := Decode(b58)
if num != i {
t.Fatalf("Expecting %d for %s", i, b58)
}
}
}
这种“幼稚”的实现尝试将所有范围从 uint64(从 0 到 18,446,744,073,709,551,615)转换为 base58,然后再转换回 uint64,但需要太多时间。
为了更好地了解go 如何处理并发,我想知道如何使用通道或goroutines 并以最有效的方式在整个 uint64 范围内执行迭代?
是否可以分块并行处理数据,如果可以,如何实现?
提前致谢。
更新:
就像@Adrien 的回答中提到的那样,一种方法是使用t.Parallel(),但这仅适用于测试包时,无论如何,通过实现它我发现它明显变慢,它并行运行但没有速度增益。
我知道完成完整的uint64 可能需要数年时间,但我现在想要找到的是通道或 goroutine 如何可能有助于加快进程(小范围测试1<<16)可能通过使用像 https://play.golang.org/p/9U22NfrXeq 这样的东西只是一个例子。
问题不在于如何测试包,而在于什么算法、技术可以通过使用并发来更快地迭代。
【问题讨论】:
-
请注意,此测试也不能证明您的实现实际上是正确的;只有那个解码/编码匹配。如果他们都以同样的方式错了,测试将通过。您需要针对规范值进行测试以证明其正确性。
-
如果您的编码/解码可以在一个 CPU 上在一秒钟内完成 10 亿次转换(这是非常乐观的),那么您需要 60 个 CPU 才能在 10 年内完成这项任务。这是假设 goroutines 和 channels 没有开销。
-
@PaulHankin 你是完全正确的,但我的想法是试图理解如何解决这个问题,比如使用通道 goroutines 处理素数时,尽管需要数年时间我想了解更多关于如何优化它.
标签: go concurrency