黄芪味道是什么味道| 身上长白色的斑点是什么原因| 插管是什么意思| 菜粥里面放什么菜最好| 为什么一同房就有炎症| 姓丁的女孩起什么名字好| 2月21日什么星座| 被子植物是什么| 人贫血吃什么补得快| 色相是什么意思| 直接胆红素偏低是什么原因| 李健是清华什么专业| 肉包子打狗的歇后语是什么| 小孩磨牙缺什么| 感冒发烧挂什么科| 沉鱼落雁闭月羞花是什么意思| 舌系带短会有什么影响| 月经黑褐色是什么原因| 五七年属什么生肖| 宝宝发烧吃什么药| 蟑螂有什么危害| 繁什么似锦| 七夕节是什么时候| 小孩一到晚上就发烧是什么原因| 维生素D有什么食物| 岳飞为什么必须死| 空气净化器什么牌子好| 吃什么东西补铁| palace什么牌子| 头疼检查什么项目| 5月10日什么星座| 新诺明又叫什么| 突厥是现在的什么地方| 老人生日送什么礼物好| 什么是清关| 肺纤维化什么意思| 内秀是什么意思| 梦见大火烧房子是什么意思| 胃炎吃什么食物好| eeg是什么意思| us检查是什么意思| 大姑姐最怕弟媳什么| 为什么梦不到死去的亲人| 黑色加什么颜色是棕色| dsa是什么检查| 23是什么生肖| 猝死是什么原因造成的| 甲功异常有什么症状| 乙肝五项45阳性是什么意思| 老放屁是什么病的征兆| 规格型号是什么意思| 骨关节疼痛什么原因| 疣是一种什么病| 窝边草是什么意思| 蜻蜓点水是什么生肖| 红眼病用什么眼药水| 富勒烯是什么| 西瓜禁忌和什么一起吃| 艺高人胆大什么意思| 天天晚上睡觉做梦是什么原因| 冠心病用什么药| 麝香保心丸治什么病| 知己什么意思| 双鱼座什么性格| 河豚吃什么| 小孩肠胃炎吃什么药| 出国旅游需要什么手续和证件| 痛风吃什么菜比较好| 苏州市长什么级别| 吐司是什么意思| 为什么会长脂肪瘤| 胃粘膜脱落什么症状严重吗| 地包天是什么意思| 鸭跖草用什么除草剂| 家里养什么宠物好| 墨西哥人是什么人种| 熟啤酒是什么意思| 房产税什么时候开始征收| cot是什么| 什么相马| 国粹是什么| 医保定点医院是什么意思| dvt是什么意思| 脾胃虚弱吃什么食物补| 老放屁吃什么药好| 不能晒太阳是什么病| 手一直抖是什么原因| 马提尼是什么酒| 白带像豆腐渣用什么药| 脸上长白斑是什么原因引起的| 杏仁有什么好处| 什么牌子的氨基酸洗面奶好| 剑桥英语和新概念英语有什么区别| 戾是什么意思| 芥末配什么好吃| 4月25号是什么星座| 美白吃什么| 什么是摇滚| 疽是什么意思| 经常手瘾吃什么药| 玫瑰花可以和什么一起泡水喝| 在下是什么意思| 精神心理科主要治疗什么疾病| 彩超能检查什么| 环比增长什么意思| 5像什么| 肺不好吃什么| 幽门杆菌吃什么药| 金银花洗澡对婴儿有什么好处| 为什么心会痛| 总钙偏高是什么原因| 八月是什么月| 慷慨什么| 晚上八点半是什么时辰| 胆碱能性荨麻疹吃什么药| 自闭什么意思| 皮试是什么意思| 姜粉什么时候喝最好| 男人阴茎硬不起来是什么原因| 金的部首是什么| moo是什么意思| 绝膑而亡是什么意思| 首台套是什么意思| 尤文氏肉瘤是什么病| 女流之辈是什么意思| 姨妈量少是什么原因| 什么药降糖效果最好| 梦见买棺材是什么征兆| 血氨是什么检查项目| 腿毛长的男人代表什么| 人中上窄下宽代表什么| pin什么意思| 嗓子干疼是什么原因| 甲鱼和什么不能一起吃| 舌头两边有齿痕是什么原因| 什么体投地| 内膜居中是什么意思| 秋葵不能和什么一起吃| 黄晓明的老婆叫什么名字| 什么叫打板| 安利什么意思| 造纸术是什么时候发明的| 什么是外阴白斑| 皮肤过敏吃什么药| 中段尿是什么意思| 阴湿是什么病| 吃什么补津液| 什么大河| 肝什么相照| 六月中旬是什么时候| 胃镜挂什么科| 跑步配速什么意思| 孔子孟子什么关系| 嫌恶是什么意思| 管医院的是什么部门| 晚上没有睡意什么原因| 吉页读什么| 太累吃什么缓解疲劳| 血液透析是什么意思| 喉咙痛鼻塞吃什么药| 4月25号是什么星座| 珍珠粉加蜂蜜做面膜有什么作用| 什么不可| kumpoo是什么牌子| 什么姿势| 十岁女孩喜欢什么礼物| 梦见蚂蚁是什么预兆| 无功无过是什么意思| 为什么吃芒果会过敏| 电磁炉什么牌子好| 什么东西解辣| 16588a是什么尺码女装| 五体投地是什么意思| 自闭症是什么| 征信对个人有什么影响| 肝红素高是什么原因| lee中文叫什么| 桑蚕丝被有什么好处| 肺结节不能吃什么| 感冒吃什么好| 九月二十六是什么星座| 直接胆红素是什么| 米面是什么| 尿液突然变深褐色是什么原因| 荷尔蒙是什么东西起什么作用| 肛周脓肿吃什么消炎药| 头晕吃什么药| 玫琳凯属于什么档次| 什么是植物神经功能紊乱| 一树梨花压海棠什么意思| 血管瘤有什么危害吗| 林可霉素主治什么病| 哥文花园女装什么档次| 带黄金对身体有什么好处| 丁是什么意思| 蟑螂是什么样子的| 什么是头寸| 眼晴干涩模糊用什么药| 梦里梦到蛇有什么预兆| 甲硝唑吃多了有什么危害| 77年的蛇是什么命| 老匹夫是什么意思| 咽喉炎用什么药| 网红是什么意思| 36年属什么生肖| 什么时间喝牛奶最佳| 手麻脚麻是什么原因引起的| eus是什么检查| 一个月的小猫吃什么| 申是什么意思| 酒精过敏是什么症状| 肾结石术后吃什么食物最好| 耳鸣和脑鸣有什么区别| 破屋坏垣适合干什么| 甲功是查什么的| 裙带菜是什么菜| 为什么海螺里有大海的声音| 培根是什么肉| 消停是什么意思| 王是什么生肖| 老黄瓜炖什么好吃| 什么是c字裤| 减肥喝什么牛奶| 1988年什么命| 月经期间洗澡会有什么影响吗| 儿童中暑吃什么药| 减肥吃什么蔬菜| 塑料属于什么垃圾| 胸前长痘痘是什么原因| 女人取环什么时候最好| 梦见订婚是什么意思| 斯沃琪手表什么档次| 舌头发麻是什么情况| 吹弹可破的意思是什么| 孤芳不自赏什么意思| 老师为什么叫老师| yishion是什么牌子| 什么发色显皮肤白| 吃什么清理血管| 什么是比特币| 香港特首是什么级别| 锦鲤什么意思| ct腹部平扫能检查什么| 今年是什么年庚| 石棉是什么| 吃生南瓜子有什么好处| 手指甲软薄吃什么补| 跨境电商是做什么的| 特别的意思是什么| 碧玉五行属什么| 恋童癖是什么意思| 缺乏维生素b12的症状是什么| 什么原因会导致月经推迟| 刮痧是什么| 血小板计数偏高是什么意思| 晕血是什么原因| 2009年五行属什么| 虾仁和什么炒好吃| 海纳百川是什么意思| 爱心是什么意思| 戊土是什么土| 炖羊肉汤放什么调料| 不速之客是什么意思| 歌帝梵巧克力什么档次| 百度

CredentialsFileView(密码显示工具)64位 V1.05绿色版

Authors: ?agdas Bozman
Date: 2025-08-05
Category: Tooling



百度 在我国当代的法律体系中,“国家财产神圣不可侵犯”,而对于私人财产仅是“国家依照法律规定保护公民的私有财产权和继承权”,亦即国家财产的地位高于私人财产,清代的法律也与此类似,体现出“律重官物”的原则。

In this blog post, we explain how ocp-memprof helped us identify a piece of code in Alt-Ergo that needed to be improved. Simply put, a function that merges two maps was performing a lot of unnecessary allocations, negatively impacting the garbage collector's activity. A simple patch allowed us to prevent these allocations, and thus speed up Alt-Ergo's execution.

The Story

Il all started with a challenging example coming from an industrial user of Alt-Ergo, our SMT solver. It was proven by Alt-Ergo in approximately 70 seconds. This seemed abnormnally long and needed to be investigated. Unfortunately, all our tests with different options (number of triggers, case-split analysis, …) and different plugins (satML plugin, profiling plugin, fm-simplex plugin) of Alt-Ergo failed to improve the resolution time. We then profiled an execution using ocp-memprof to understand the memory behavior of this example.

Profiling an Execution with ocp-memprof

As usual, profiling an OCaml application with ocp-memprof is very simple (see the user manual for more details). We just compiled Alt-Ergo in the OPAM switch for ocp-memprof (version 4.01.0+ocp1) and executed the following command:

$ ocp-memprof -exec ./ae-4.01.0+ocp1-public-without-patch pb-many-GCs.why

The execution above triggers 612 garbage collections in about 114 seconds. The analysis of the generated dumps produces the evolution graph below. We notice on the graph that:

  • we have approximately 10 MB of hash-tables allocated since the beginning of the execution, which is expected;
  • the second most allocated data in the major heap are maps, and they keep growing during the execution of Alt-Ergo.

We are not able to precisely identify the allocation origins of the maps in this graph (maps are generic structures that are intensively used in Alt-Ergo). To investigate further, we wanted to know if some global value was abnormally retaining a lot of memory, or if some (non recursive-terminal) iterator was causing some trouble when applied on huge data structures. For that, we extended the analysis with the --per-root option to focus on the memory graph of the last dump. This is done by executing the following command, where 4242 is the PID of the process launched by ocp-memprof --exec in the previous command:

$ ocp-memprof -load 4242 -per-root 611

The per-root graph (above, on the right) gives more interesting information. When expanding the stack node and sorting the sixth column in decreasing order, we notice that:

  • a bunch of these maps are still in the stack: the item Map_at_192_offset_1 in the first column means that most of the memory is retained by the fold function, at line 192 of the Map module (resolution of stack frames is only available in the commercial version of ocp-memprof);
  • the "kind" column corresponding to Map_at_192_offset_1 gives better information. It provides the signature of the function passed to fold. This information is already provided by the online version.
Uf.Make(Uf.??Make.X).LX.t ->;
Explanation.t ->;
Explanation.t Map.Make(Uf.Make(Uf.??Make.X).LX).t ->;
Explanation.t Map.Make(Uf.Make(Uf.??Make.X).LX).t

This information allows us to see the precise origin of the allocation: the map of module LX used in uf.ml. Lucky us, there is only one fold function of LX's maps in the Uf module with the same type.

Optimizing the Code

Thanks to the information provided by the --per-root option, we identified the code responsible for this behavior:

(*** function extracted from module uf.ml ***)
module MapL = Map.Make(LX)

let update_neqs r1 r2 dep env =
let merge_disjoint_maps l1 ex1 mapl =
try
let ex2 = MapL.find l1 mapl in
let ex = Ex.union (Ex.union ex1 ex2) dep in
raise (Inconsistent (ex, cl_extract env))
with Not_found ->;
MapL.add l1 (Ex.union ex1 dep) mapl
in
let nq_r1 = lookup_for_neqs env r1 in
let nq_r2 = lookup_for_neqs env r2 in
let mapl = MapL.fold merge_disjoint_maps nq_r1 nq_r2 in
MapX.add r2 mapl (MapX.add r1 mapl env.neqs)

Roughly speaking, the function above retrieves two maps nq_r1 and nq_r2 from env, and folds on the first one while providing the second map as an accumulator. The local function merge_disjoint_maps (passed to fold) raises Exception.Inconsistent if the original maps were not disjoint. Otherwise, it adds the current binding (after updating the corresponding value) to the accumulator. Finally, the result mapl of the fold is used to update the values of r1 and r2 in env.neqs.

After further debugging, we observed that one of the maps (nq_r1 and nq_r2) is always empty in our situation. A straightforward fix consists in testing whether one of these two maps is empty. If it is the case, we simply return the other map. Here is the corresponding code:

(*** first patch: testing if one of the maps is empty ***)
…
let mapl =
if MapL.is_empty nq_r1 then nq_r2
else
if MapL.is_empty nq_r2 then nq_r1
else MapL.fold_merge merge_disjoint_maps nq_r1 nq_r2
…

Of course, a more generic solution should not just test for emptiness, but should fold on the smallest map. In the second patch below, we used a slightly modified version of OCaml's maps that exports the height function (implemented in constant time). This way, we always fold on the smallest map while providing the biggest one as an accumulator.

(*** second (better) patch : folding on the smallest map ***)
…
let small, big =
if MapL.height nq_r1 > MapL.height nq_r2 then nq_r1, nq_r2
else nq_r2, nq_r1
in
let mapl = MapL.fold merge_disjoint_maps small big in
…

Checking the Efficiency of our Patch

Curious to see the result of the patch ? We regenerate the evolution and memory graphs of the patched code (fix 1), and we noticed:

  • a better resolution time: from 69 seconds to 16 seconds;
  • less garbage collection : from 53,000 minor collections to 19,000;
  • a smaller memory footprint : from 26 MB to 24 MB;

Conclusion

We show in this post that ocp-memprof can also be used to optimize your code, not only by decreasing memory usage, but by improving the speed of your application. The interactive graphs are online in our gallery of examples if you want to see and explore them (without the patch and with the patch).

AE AE + patch Remarks
4.01.0 69.1 secs 16.4 secs substantial improvement on the example
4.01.0+ocp1 76.3 secs 17.1 secs when using the patched version of Alt-Ergo
dumps generation 114.3 secs (+49%) 17.6 secs (+2.8%) (important) overhead when dumping
memory snapshots
# dumps (major collections) 612 GCs 31 GCs impressive GC activity without the patch
dumps analysis
(online ocp-memprof)
759 secs 24.3 secs
dumps analysis
(commercial ocp-memprof)
153 secs 3.7 secs analysis with commercial ocp-memprof is
**~ x5 faster** than public version (above)
AE memory footprint 26 MB 24 MB memory consumption is comparable
minor collections 53K 19K fewer minor GCs thanks to the patch
Do not hesitate to use `ocp-memprof` on your applications. Of course, all feedback and suggestions are welcome, just [email](mailto:contact@ocamlpro.com) us !

More information:



About OCamlPro:

OCamlPro is a R&D lab founded in 2011, with the mission to help industrial users benefit from experts with a state-of-the-art knowledge of programming languages theory and practice.

  • We provide audit, support, custom developer tools and training for both the most modern languages, such as Rust, Wasm and OCaml, and for legacy languages, such as COBOL or even home-made domain-specific languages;
  • We design, create and implement software with great added-value for our clients. High complexity is not a problem for our PhD-level experts. For example, we helped the French Income Tax Administration re-adapt and improve their internally kept M language, we designed a DSL to model and express revenue streams in the Cinema Industry, codename Niagara, and we also developed the prototype of the Tezos proof-of-stake blockchain from 2014 to 2018.
  • We have a long history of creating open-source projects, such as the Opam package manager, the LearnOCaml web platform, and contributing to other ones, such as the Flambda optimizing compiler, or the GnuCOBOL compiler.
  • We are also experts of Formal Methods, developing tools such as our SMT Solver Alt-Ergo (check our Alt-Ergo Users' Club) and using them to prove safety or security properties of programs.

Please reach out, we'll be delighted to discuss your challenges: contact@ocamlpro.com or book a quick discussion.


基底是什么意思 丙型肝炎病毒抗体阴性什么意思 教师节送什么礼物好 什么品种荔枝最好吃 为什么腋窝老是出汗
什么病不能吃牛肉 心率过快是什么原因 朗朗原名叫什么 硬盘是什么 螃蟹不能和什么水果一起吃
灵芝泡水喝有什么好处 什么情况下吃丹参滴丸 脖子粗大是什么病的症状 空调抽湿是什么意思 黄鳝吃什么东西长得快
鸡蛋壳薄是什么原因 张衡发明了什么东西 女人小腹痛什么原因 表面抗原阳性是什么意思 为什么早上起来眼睛肿
眼睛视力模糊用什么眼药水qingzhougame.com 溶豆是什么luyiluode.com 怂恿是什么意思hcv9jop4ns6r.cn 造化弄人是什么意思hcv8jop3ns4r.cn 什么是神经性皮炎hcv9jop7ns3r.cn
胆囊炎吃什么水果好hcv9jop7ns2r.cn 做完胃镜可以吃什么hcv8jop8ns0r.cn 鼻梁痛什么原因引起的hcv9jop6ns8r.cn 合卺是什么意思hkuteam.com 小孩子经常流鼻血是什么原因hcv9jop2ns4r.cn
夏天吃什么降火naasee.com 主意正是什么意思hcv9jop7ns0r.cn 肝火旺盛是什么原因引起的hcv8jop5ns1r.cn 终年是什么意思hcv9jop1ns2r.cn 身上起小红点是什么原因hcv7jop5ns5r.cn
补钙有什么好处bysq.com 七九年属什么生肖hcv7jop5ns2r.cn 青储是什么hcv7jop5ns3r.cn 腋臭手术挂什么科wuhaiwuya.com 吃的少还胖什么原因hcv8jop9ns6r.cn
百度