Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/amazon-s3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala[2.11.6]——有没有一种优雅的方法可以基于Int/Long和完整的类名为对象创建缓存键?_Scala_Caching - Fatal编程技术网

Scala[2.11.6]——有没有一种优雅的方法可以基于Int/Long和完整的类名为对象创建缓存键?

Scala[2.11.6]——有没有一种优雅的方法可以基于Int/Long和完整的类名为对象创建缓存键?,scala,caching,Scala,Caching,我想使用缓存来保存刚从数据库读取的最近访问的对象 在我的例子中,数据库主键将是一个很长的过程 在每种情况下,我都会有一个表示此数据的对象(case类) Long加上完整类名的组合将是查找任何特定对象的唯一标识符。(名称空间不应该有冲突,因为类名不使用数字(作为一项规则?)。在任何情况下,对于这种使用情况,我控制整个名称空间,因此没有太大的问题) 这些对象在缓存中的寿命相对较短——我只看到了一些情况,在这些情况下,我可以通过多次保存同一个不可变对象来节省内存,而同一对象的不同实例则极难“到处传递”

我想使用缓存来保存刚从数据库读取的最近访问的对象

在我的例子中,数据库主键将是一个很长的过程

在每种情况下,我都会有一个表示此数据的对象(case类)

Long加上完整类名的组合将是查找任何特定对象的唯一标识符。(名称空间不应该有冲突,因为类名不使用数字(作为一项规则?)。在任何情况下,对于这种使用情况,我控制整个名称空间,因此没有太大的问题)

这些对象在缓存中的寿命相对较短——我只看到了一些情况,在这些情况下,我可以通过多次保存同一个不可变对象来节省内存,而同一对象的不同实例则极难“到处传递”以避免

这也有助于在不同的眼球检查相同的东西的情况下提高性能,但这不是这个特定用例的驱动因素(只是肉汁)

我现在关心的是每一次我需要一个给定的对象,我需要重新创建缓存密钥。这将涉及一个Long.toString和一个字符串Concat。所讨论的case类在其同伴对象中有一个val,这样它们就知道自己的类名,而不会发生任何进一步的反射

我正在考虑在主缓存键的伴生对象中放置一个“缓存”,因为我希望避免每次查找(不必要的?)重复操作,以及由此产生的垃圾收集等(运行最快的代码是永远不会被写入(或调用)的代码-对吗?)

有没有更优雅的方法来处理这个问题?是否有其他人已经解决了这个具体问题

我曾想过编写一个key类,但即使使用val(lazy或其他)作为hash和toString,我仍然会得到我请求的每个对象的命中率,因为现在我每次都必须创建key对象。(这当然可以返回到伴生对象密钥缓存中,但如果我费事为密钥设置伴生对象缓存,则密钥对象方法是多余的。)

作为这个问题的第二个问题——假设我使用一个长的完整的类名(作为字符串),它最有可能得到最快的缓存拉

Long.toString + fullClassName

Long是键中的一个字符串,所以假设它是缓存上的一个字符串“find”,那么索引查找会更容易?首先是数字部分或字符串类名

“数字优先”表示您使用匹配的数字遍历所有对象以搜索匹配的类,而“类优先”表示您首先查找特定类的块,但您必须转到字符串的最末端以查找精确匹配

我怀疑前者可能更容易为“快速查找”进行优化(我知道用MySQL术语来说应该是…)


也许有人已经有了基于双键查找的缓存?:)

我会让它非常简单,直到你有了具体的性能指标。比如:

trait Key {

  def id: Long

  lazy val key: String = s"${getClass.getName}-${id}"

}

case class MyRecordObject(id: Long, ...) extends Key
使用简单的现有缓存解决方案,如

至于你的第二个问题,我根本不会担心生成密钥的性能,除非你能证明生成密钥是一个瓶颈(我有点怀疑它是否会是)

事实证明,
Cache.getOrElse[T](idAsString,秒)
实际上完成了大部分繁重的工作

[T] 当然是Scala中的
类型
,这足以使缓存中的内容保持分离。每个[T]都是缓存中唯一、独立且不同的存储桶

因此,
Cache.getOrElse[AUser](10,5)
将从
Cache.getOrElse[ALog](10,5)
获得一个完全不同的对象(其中10的ID恰好与此处的说明相同)

我目前正在对数百种类型的数千个对象执行此操作,因此我知道它是有效的

我说大部分的工作都需要
.toString
”才能用作键。这不是一个完整的GC灾难,因为我只是简单地设置了一个映射来保存最常见/最近的
.toString
'ed长值

对于那些根本不了解这一点的人来说,考虑一个简单的日志屏幕,这在大多数Web应用程序中非常普遍。p>

2015/10/22 10:22 - Johnny Rotten - deleted an important file
2015/10/22 10:22 - Johnny Rotten - deleted another important file
2015/10/22 10:22 - Johnny Rotten - looked up another user
2015/10/22 10:22 - Johnny Rotten - added a bogus file
2015/10/22 10:22 - Johnny Rotten - insulted his boss
在Java(Tomcat)下,通常会有一个表示该用户(Johnny Rott)的单个对象,并且每当该用户的名称出现在日志显示中时,该单个对象都会链接到该对象

现在,在Scala下,我们倾向于为日志条目的每一行创建一个新实例(Case类),这仅仅是因为我们没有(高效/管道)方法来获取该Case类最后使用的实例。日志本身往往是一个case类,它具有User case类的
lazy val

因此,user-x出现了,他们查找一个日志,将分页设置为500行或更低,现在我们创建了500个case类,只是为了显示一个用户名(每个日志条目中的“who”)

几秒钟后,我们又有500个
用户
案例类,当他们点击刷新时,因为他们不认为他们第一次点击鼠标右键

然而,对于一个简单的缓存,它可以保存一个最近访问过的对象长达5秒钟,我们为整个500个日志条目创建的只是一个
User
Case类的单个实例,用于日志中显示的每个唯一名称


在Scala中,Case类是不可变的,因此这里的单个实例是完全可以接受的用例,GC没有不必要的工作要做

该应用程序将存在多少个实例?如果有多个应用程序实例,您是假设一个分布式缓存还是每个应用程序实例都有自己的缓存
import play.api.cache.Cache
2015/10/22 10:22 - Johnny Rotten - deleted an important file
2015/10/22 10:22 - Johnny Rotten - deleted another important file
2015/10/22 10:22 - Johnny Rotten - looked up another user
2015/10/22 10:22 - Johnny Rotten - added a bogus file
2015/10/22 10:22 - Johnny Rotten - insulted his boss