- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
我有一个用例,我需要计算很多集合之间的相似性以创建一个简单的推荐引擎。我正在查看 Jaccard 系数和其他相似系数公式,但它们之间有一个共同点:集合中的项目不能重复(如果我在这里错了请纠正我)。
我用 PHP 编写了自己的函数来执行自定义哈希交集,其逻辑是:
arr1
:一个数组,其键是项目的id,值是它们对应的数量。这代表用户的愿望 list 。arr2
:与 arr1
相同,但它代表另一个用户的库存。我需要一种非常快速的方法来对集合进行求交,但通常的相似系数公式涉及集合的求交和并集,当将一个集合与 200k 其他集合进行比较时,这可能没有我想要的那么快。这是我目前所处的位置:
function my_similarity_coefficient ($arr1, $arr2) {
$matches = 0;
$total = 0;
if (count($arr2) == 0)
return 0;
foreach ($arr1 as $id => $qty) {
$total += $qty;
if (!array_key_exists($id, $arr2))
continue;
$matches += min($qty, $arr2[$id]); // do not match more than what user wants
}
return $matches / $total;
}
我尝试在 PHP 中将两个红色散列相交。大小分别为 arr1[67]
和 arr2[231]
。该系数是在出色的 61.98 微秒(最坏情况下高达 266.075 微秒)下计算得出的。如果我尝试将数据从 Redis 获取到 PHP,这个数字会膨胀到 905.037µsec-3337.86µsec。
我想避免将数据从 redis 传输到 PHP 的瓶颈,所以我想知道是否可以在 lua(或者甚至是 c++)中对这个自定义交集进行编程,如果可能的话,它不会受到影响吗来自相同的瓶颈,因为它也从 pointA 获取它到 pointB,或者它不会遇到获取瓶颈,因为数据已经在它的本地了吗?
我不熟悉 lua,但我不想被灌输精确的代码。由于网上关于lua的资源与我真正想要实现的相关的很少,所以我想先在这里挑几个脑筋,同时搜索。
最佳答案
让我们看看。首先,这是直接翻译成 Lua 的 PHP 代码。我在这里保留了相同的变量名,但是您在 PHP 中称为“Array”的在 Lua 中称为“Table”。
local my_similarity_coefficient = function(arr1, arr2)
local matches = 0
local total = 0
if next(arr2) == nil then
return 0
end
for id, qty in pairs(arr1) do
total = total + qty
if arr2[id] then
matches = matches + math.min(qty, arr2[id])
end
end
return matches / total
end
请注意,如果 arr1
为空,此代码可以除以零,但您的也可以。
让我们试试看:
local arr1 = {
a = 3,
b = 5,
c = 8,
}
local arr2 = {
a = 2,
c = 10,
d = 7,
e = 21,
}
print(my_similarity_coefficient(arr1, arr2)) -- 0.625
现在让我们使用 Redis。首先,让我们创建测试数据。
redis 127.0.0.1:6379> hmset arr1 a 3 b 5 c 8
OK
redis 127.0.0.1:6379> hmset arr2 a 2 c 10 d 7 e 21
OK
这个脚本做你想做的,不是以最有效的方式(对 redis.call
的调用可能更少)而是以一种简单的方式,所以你可以理解它并在需要时优化它:
local k1, k2 = KEYS[1], KEYS[2]
local matches, total = 0, 0
if not redis.call("exists", k2) then return 0 end
local qty, qty2
for _, id in ipairs(redis.call("hkeys", k1)) do
qty = tonumber(redis.call("hget", k1, id))
total = total + qty
qty2 = tonumber(redis.call("hget", k2, id) or 0)
matches = matches + math.min(qty, qty2)
end
return tostring(matches / total)
我们称它为:
$ redis-cli eval "$(cat the_script.lua)" 2 arr1 arr2
"0.625"
成功!
需要注意的重点是类型转换:值(数量)使用 tonumber
转换为整数(Redis 返回字符串),我们将结果转换为字符串,因为如果我们返回一个 float Redis 会将其截断为整数(此处为 0)。
编辑 - 好的,谈论优化而不是说如何不好,所以这是一个简单的:
local k1, k2 = KEYS[1], KEYS[2]
local matches, total = 0, 0
if not redis.call("exists", k2) then return 0 end
local t1 = redis.call("hgetall", k1)
local id, qty, qty2
for i=1,#t1,2 do
id, qty = t1[i], tonumber(t1[i+1])
total = total + qty
qty2 = tonumber(redis.call("hget", k2, id) or 0)
matches = matches + math.min(qty, qty2)
end
return tostring(matches / total)
关于lua - redis + lua 可能有哈希交集吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19801923/
如何从 a.lua 传递值至 b.lua ? 让我们说在我的 a.lua我有这个变量代码。 local value = "Hello WOrld!" director:changeScene ("b"
我有一个使用命令行解释器运行的 lua 脚本,该脚本需要从文件加载表。 该表存储如下: create_object_action = { reflexive = true, which
我通过静态链接的方式在我的项目中嵌入了 Win32 上的 Lua(不,我不能切换到 DLL)。我想捆绑更多使用 native 代码的 Lua 扩展 - 而不仅仅是纯 .lua 文件。具体来说,我想捆绑
我需要一些帮助来解析 lua 文件的命令行。我正在执行一个 lua 文件,该 lua 文件有一个命令“dofile(2nd.lua-file)”,但是,我想通过第一个 lua 文件将一些参数传递给第二
这是我的代码示例: listOfPeople = {} listOfPeople["test"] = "hello" listOfPeople = nil “hello”字符串是否丢失并形成内存泄漏?
在一些源代码中,我看到了“Underscore.lua”模块的用法。 _ = require 'underscore' 描述如下: Underscore.lua is a Lua library th
在一些源代码中,我看到了“Underscore.lua”模块的用法。 _ = require 'underscore' 描述如下: Underscore.lua is a Lua library th
我一直在编程 io.write("How many languages do you speak?\n") answer = io.read() if (answer == 1) then io.wr
这个问题在这里已经有了答案: Getting multiple values from a function without creating a variables in LUA (2 个答案)
在阅读 Lua manual 时我遇到了这部分: 函数调用和赋值都可以以左括号开头。这种可能性导致了 Lua 语法中的歧义。考虑以下片段: a = b + c (print or io.write)(
假设我有以下循环: for name in poll() do if name == "quit" then return 0 end end "quit" 字符串是否
Pandoc 通过其 --lua-filter 参数原生支持 lua 过滤器。 但是,我想知道它使用的是什么版本的 lua,以及是否可以将 lua 模块(我相信它依赖于 C 代码)导入其中。 这是我调
这种语言是面向对象的语言吗? 它经常用作OO语言吗? 最佳答案 Lua 完全有能力 prototype-based类似于 JavaScript 的面向对象编程。 Prototype-based pro
我想从 C++ 传递一个 Lua 脚本(Lua 解释器可以处理的代码)并取回结果。 我在网上查看,但找不到任何可以帮助我的示例。我可以从 C++ 调用 Lua 函数,但这需要您使用 Lua 函数创建一
我正在阅读“在 Lua 中编程”,但我不明白这段代码中 Lua 中函数的行为: function newCounter () local i = 0 return function () --
我最近一直在查找 Lua 中的链表,并有一个简单的问题,到目前为止我还没有找到答案 local head = nil head = {next = head, value = "d"} head =
我知道有tonumber()函数,但是问题是我需要转换较大的数字,例如1000100110100011111010101001001001001100100101。我可以自己写,但是有没有办法将其集成
是否可以在 Lua 中对多个值执行算术运算。 我在 Windows 5.1.4 上使用 Lua。 目前我必须将多个值放入一个表中,然后解压缩它们,我希望能够跳过这一步。 是否可以。 这是我目前拥有的:
有什么区别吗 local splitPathFileExtension = function (res) end 和 function splitPathFileExtension(res) end
在下面的代码中,谁能解释一下 b,a = a,b 内部是如何工作的? -- Variable definition: local a, b -- Initialization a = 10 b = 3
我是一名优秀的程序员,十分优秀!