存储中的字符串是不是一定小于 Vector3?

Posted

技术标签:

【中文标题】存储中的字符串是不是一定小于 Vector3?【英文标题】:Is a string necessarily smaller than a Vector3 in storage?存储中的字符串是否一定小于 Vector3? 【发布时间】:2021-05-29 22:15:06 【问题描述】:

我正在 Core 中开发一个系统来保存家具的变换,特别是位置和旋转,它们都是 Vector3 的。我有这些在玩家存储中,所以在某些时候为了保存所有玩家的家具,我想我最终会最大化玩家存储。因此,我将所有 Vector3 转换为字符串,并使用我发现的 Roblox 脚本的修改版本:

local API = 

API.VectorToString = function(vec)
    return math.floor(vec.x*100)/100 ..' '.. math.floor(vec.y*100)/100 ..' '.. math.floor(vec.z*100)/100
end

API.StringToVector = function(str)
    local tab = 
    for a in string.gmatch(str,"(%-?%d*%.?%d+)") do
        table.insert(tab,a)
    end
    return Vector3.New(tab[1],tab[2],tab[3])
end

return API

所以问题是,将所有这些向量转换为字符串真的可以节省我的玩家数据存储空间吗?

【问题讨论】:

这取决于你有多少位数。无论值如何,Vector3 都将始终消耗相同的内存。字符串内存大小取决于您用它表示的位数。你为什么不试试看,自己比较一下? 【参考方案1】:

Vector3 格式很可能比存储的字符串转换更有效。 Vector3 中的每个数字都需要存储 4 个字节,因为每个数字都是 16 位浮点数。通过将 Vector3 值转换为字符串,需要额外的字节(您添加的每个数字都需要一个字节,因为一个字符需要一个字节)。如果您需要将 Vector3 存储为字符串,我建议您使用以下方法。

对于任何想了解计算机如何仅在四个字节中存储如此广泛的数字的人,我强烈建议研究 IEEE 754 格式。

Video that explains the IEEE754 Format

您可以使用 string.packstring.unpack 函数将浮点数转换为可以作为字符串发送的字节数组。此方法在发送数据时总共只需要 12 个字节(12 个字符),并且具有大约 5 到 6 个小数点的精度。虽然这种方法可能只节省几个字节,但它可以让您发送/保存更精确的数字/位置。

local API = 

API.VectorToString = function(vec) 
    --Convert the x,y,z positions to bytes 
    local byteXValue = string.pack('f', vec.x, 0) 
    local byteYValue = string.pack('f', vec.y, 0) 
    local byteZValue = string.pack('f', vec.z, 0) 
    --Combine the floats bytes into one string
    local combinedBytes = byteXValue + byteYValue + byteZValue
    return combinedBytes 
end

API.StringToVector = function(str) 
    --Convert the x,y,z positions from bytes to float values
    --Every 4th byte represents a new float value
    local byteXValue = string.unpack('f', string.sub(1, 4)) 
    local byteYValue = string.unpack('f', string.sub(5, 8)) 
    local byteZValue = string.unpack('f', string.sub(9, 12)) 
    --Combine the x,y,z values into one Vector3 object
    return Vector3.New(byteXValue, byteYValue, byteZValue) 
end

return API

String pack function documentation

【讨论】:

【参考方案2】:

它可以写得更短一些,内存分配更少

    local v3 = Vector3.New(111, 222, 333)
    local v3str = string.pack("fff", v3.x, v3.y, v3.z)
    local x, y, z = string.unpack("fff", v3str)
    local v31 = Vector3.New(x, y, z)
    assert(v3 == v31)

但您需要记住,大多数核心 API 函数不允许字符串中的零字节,如果您想将这些字符串存储在 Storage 中或将它们用作事件参数 - 您应该对它们进行文本编码(Base64 是常用选项)。

【讨论】:

以上是关于存储中的字符串是不是一定小于 Vector3?的主要内容,如果未能解决你的问题,请参考以下文章

检查第一个字符串是不是小于或等于第二个字符串中的相应字母

VBA如果单元格小于一定长度,突出显示并显示消息

unity项目字符串转为Vector3和Quaternion

XNA中是否有Vector3Int等效?

在 MySQL 中存储 Vector3

使用存储过程检查字符串是不是包含 SQL Server 2005 中的子字符串