隔离Lua和本地化。

我正在考虑将Lua嵌入到C++应用程序中(在FreeBSD 8.2下运行)。但是基准测试显示,在某些情况下性能较差。特别是当Lua尝试将字符串转换为数字并比较字符串时,它变得更慢,并且更糟糕的是影响了可伸缩性(8个核的性能比一个还要差!)。我现在认为这是与本地化有关,因为当我避免自动转换时一切正常。但是在现实生活中,我将需要进行字符串比较和数字转换。我该如何:

  1. 隔离Lua不受本地化影响,即确保Lua的函数都不会间接使用本地化。例如,我可以提供自己的转换和比较函数吗?

  2. 或者完全禁用本地化。我尝试了setlocale(LC_ALL,"C"),它工作正常(本地化更改),但瓶颈仍然存在。

更新:

按照lhf的建议,我立即跳入Lua库代码。我发现有几十个地方(官方)使用了依赖本地化的函数。要删除它们中的所有函数将耗费太多的精力,必须有更好的方法。我尝试测量它们中哪些不具有可扩展性。我还添加了一些其他常用的函数,以及我自己感兴趣的一些函数(创建和销毁Lua解释器,设置全局变量等)。结果如下。正确的百分比必须是700%,即7个线程必须比1个线程表现好7倍:

           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双精度转换在单个线程上表现更差。时间和gettimeofday的可伸缩性不佳。用%s格式的sscanf也具有很差的可扩展性,这相当令人惊讶,但在我的情况下不是问题。

最后,可能根本不是本地化的问题。我将Lua的转换从sprintf更改为一些简化的手工制作代码,到目前为止一切都运行良好。

顺便说一下,第一个基准测试在linux桌面上运行,并没有显示出如此奇怪的情况。我对FreeBSD的行为感到惊讶。

原文链接 https://stackoverflow.com/questions/5779019

点赞
stackoverflow用户107090
stackoverflow用户107090

为避免在字符串比较中出现本地化问题,在 lvm.c 中将 strcoll 更改为 strcmp。为避免在字符串转数字中出现本地化问题,在 luaconf.h 中更改 lua_str2number 的定义以避免使用 strtod。(但请注意,使用自己的 strtod 并不是一项容易的任务。)您还可以在 llex.c 中删除 trydecpoint

2011-04-25 14:46:21