我在网上的不同地方看到了一些关于此的相互矛盾的信息,所以希望得到真正知道的人的权威回答。
假设,我正在将一些内容序列化为 avro:
class StuffToAvro {
private final Schema schema;
StuffToAvro(Schema schema) { this.schema = schema }
void apply(GenericRecord stuff, OutputStream out) {
final Encoder encoder = EncoderFactory.get.binaryEncoder(out, null);
final GenericDatumWriter writer = new GenericDatumWriter(schema);
writer.write(stuff, encoder):
}
}
Run Code Online (Sandbox Code Playgroud)
问题是我是否可以/应该通过重用编码器和编写器来优化它,如果我应该这样做,正确的方法是什么:我可以预先初始化编写器并使其final例如,还是需要是一个ThreadLocal?
关于编码器的类似问题:我应该记住前一个实例并将其传递getBinaryEncoder给重用,还是也需要一个ThreadLocal。
在每种情况下,如果答案是ThreadLocal,我还想知道这种优化是否值得复杂化:每次创建全新的编写器和/或编码器而不是重用它们实际上是否昂贵?
另外,我假设,无论我在这里得到什么答案,也适用于阅读/解码。那正确吗?
感谢任何指针。
谢谢!
我一直在阅读有关 Dotty 的文章,因为它看起来即将成为 Scala 3,并注意到类型投影被认为是“不健全的”并从语言中删除......
这似乎很糟糕,因为我已经看到了几个非常有用的用例。例如:
trait Contents
class Foo extends Contents
class Bar extends Contents
trait Container[T <: Contents] { type ContentType = T }
class FooContainer extends Container[Foo]
class BarContainer extends Container[Bar]
trait Manager[T <: Container[_]] {
type ContainerType = T
type ContentType = T#ContentType
def getContents: ContentType
def createContainer(contents: ContentType): ContainerType
}
Run Code Online (Sandbox Code Playgroud)
如何在 Dotty 中做这样的事情?将第二个类型参数添加到Manager? 但是,除了创建和操作 的实例变得非常乏味这一事实之外Manager,它也不太有效,因为没有办法强制执行这两种类型之间的关系(Manager[FooContainer, Bar]不应该是合法的)。
然后,还有其他用途,如类型 lambdas 和部分应用类型,可用于创建有偏差的函子等……或者这些(部分应用类型)是否成为 Dotty 中的“一等公民”?
编辑
为了回答评论中的问题,这里有一个有点人为的例子,可以使用他的 this 。让我们假设,我Managers实际上是 Akka Actors …
的文档中有一些令人恐惧的语言groupByKey,警告它可能“非常昂贵”,并建议尽可能使用它aggregateByKey。
我想知道成本的差异是否来自这样的事实:对于某些聚合,永远不需要收集整个组并将其加载到同一节点,或者在实现上是否存在其他差异。
基本上,问题是它是否rdd.groupByKey()等同于rdd.aggregateByKey(Nil)(_ :+ _, _ ++ _)或是否仍会更昂贵。
我刚开始使用kotlin,所以请原谅我,如果这是一个基本问题,我确实做了一些谷歌搜索,但这并没有发现任何有用的东西.
问题是如何将值转换为Unit.例如,在scala中,如果我写这样的东西:
def foo: Int = ???
def bar(x: String): Unit = x match {
case "error" => println("There was an error")
case _ => foo
Run Code Online (Sandbox Code Playgroud)
}
match表达式的返回类型是Any,但它被编译器丢弃并由Unit函数返回.
但是在kotlin做这样的事情:
fun bar(x: String): Unit = when(x) {
"error" -> println("There was an error")
else -> foo()
}
Run Code Online (Sandbox Code Playgroud)
它抱怨这foo部分:inferred type is Int but Unit was expected
我知道,在这种情况下,我可以摆脱它=,并把身体放在一个块内,这是有效的,但我正在寻找一个通用的解决方案.到目前为止我能够得到的只是foo.let {},但它看起来有点笨拙,特别是如果有很多这样的情况需要完成.
class Bar { override def toString() = "Bar" }
case class Foo(s: String) extends Bar
Foo("bar") // "Bar"
Run Code Online (Sandbox Code Playgroud)
为什么不生成Foo它toString?这是一个错误还是实际上有原因?有没有办法"把它取回"(是否有一个默认的实现可能适用于案例类)?
这段代码:
package main
import (
"fmt"
"encoding/json"
)
type State struct { Foo string }
type Handler struct { state State }
func (handler Handler) State() *State { return &handler.state }
func main() {
input := `{"Foo": "bar"}`
handler := Handler{}
state := handler.State()
json.Unmarshal([]byte(input), state)
fmt.Printf("%v\n", state)
fmt.Printf("%v\n", handler.state)
}
Run Code Online (Sandbox Code Playgroud)
打印
&{bar}
{}
Run Code Online (Sandbox Code Playgroud)
(亲自看看)
这会让我感到厌烦:handle.State()返回地址handler.state,那么怎么可能state(最终&handler.state)handler.state包含不同的东西(一个是空的,另一个不是)?
如果我改变state := handler.State()到state := &handler.state,那么它的工作原理我希望它的方式.
我在这里错过了什么?