我正在考虑在c++应用程序中嵌入Lua(在FreeBSD 8.2下运行)。但基准测试显示,在某些情况下,表现不佳。特别是当Lua试图将字符串转换为数字并比较字符串时,它会变得更慢,更糟糕的是,会破坏可伸缩性(8核的性能比1核更差!)。我现在认为这是区域设置,因为当我避免自动转换一切工作正常。但在现实生活中,我将需要字符串比较和数字转换。如何:
-
将Lua与locale隔离开来,即确保Lua的函数都不间接使用locale。例如,我可以提供自己的转换和比较函数吗?
-
或完全禁用区域设置。我尝试了
setlocale (LC_ALL, "C")
,它工作正常(区域设置更改),但瓶颈仍然存在
nop: 824% (1:106867300/7:881101495)
sprintf %f: 57% (1:2093975/7:1203949)
sprintf %.14g: 51% (1:2503818/7:1278312)
sprintf %.14lf: 73% (1:2134432/7:1576657)
sprintf %lf: 64% (1:2083480/7:1340885)
sprintf %d: 601% (1:6388005/7:38426161)
sscanf %s: 181% (1:8484822/7:15439285)
sscanf %f: 712% (1:3722659/7:26511335)
lua_cycle: 677% (1:113483/7:768936)
set_global: 715% (1:1506045/7:10780282)
set_get_global: 605% (1:2814992/7:17044081)
strcoll: 670% (1:38361144/7:257300597)
getenv: 681% (1:8526168/7:58131030)
isdigit: 695% (1:106894420/7:743529202)
isalpha: 662% (1:80771002/7:535055196)
isalpha(r): 638% (1:78232353/7:499207555)
strtol: 694% (1:16865106/7:117208528)
strtod: 749% (1:16727244/7:125323881)
time: 168% (1:727666/7:1225499)
gettimeofday: 162% (1:727549/7:1183433)
在不同的运行中,数据有所不同,但总体情况是一致的:sprintf双线程转换的性能比单线程转换差。时间和时间的比例很糟糕。带有%s的Sscanf的可伸缩性也很差,这很令人惊讶,但在我的例子中不是问题。
最后,它可能根本不是locale。我将Lua转换从sprintf转换为一些简化的手工代码,到目前为止一切都运行良好。
顺便说一句,第一个基准测试是在linux桌面上运行的,没有什么奇怪的。
为了避免字符串比较中的区域设置,请将lvm.c
中的strcoll
更改为strcmp
。要避免字符串到数字转换中的区域设置,请更改luaconf.h
中lua_str2number
的定义以避免strtod
。(请注意,提供自己的strtod
并不是一件容易的事。)您也可以在llex.c
中删除trydecpoint
。