浅谈注册表读取所需要付出的性能代价

news2024/9/23 17:23:19

Windows 系统的特色功能,注册表,是一个十分方便有用的工具。它可以用来以一种统一和多线程安全的方式来永久性的保存数据。如果你将数据保存在 HKEY_CURRENT_USER 键下,则数据可以随着用户一起漫游,并且可以保护单个键值 (即使是在使用了 FAT 文件系统的操作系统也是如此)。

但这并不意味着这是一份免费的午餐。

据我所知,从打开注册表键开始,读取键值并关闭它,整个过程将花费大约 60000 到 100000 个 CPU 周期,这还是假定要查找的键值已经缓存在内存中的情况。如果你打开注册表键并保持打开状态,那么读取值的行为大约需要 15000 到 20000 个 CPU 周期(这些测算数据是 Windows XP 下的估计值,在真实情况下数据可能会有所不同)。

因此,我们不应在一个内部循环中读取注册表项。它不仅会在查询时花费 CPU 时间,而且注册表的不断查询意味着,注册表用于查找和存储键(包括注册表缓存中的条目)的数据结构将始终保存在系统工作集中。

另外,也不要在每次鼠标移动时读取注册表项,应该仅读取该值一次并缓存结果。

如果你担心用户在程序运行时修改了键值,则可以考虑建立一个规则,供人们在想要更改设置时遵循。
例如,Windows 使用诸如 SystemParametersInfo 之类的函数,在通常情况下,会首先读写缓存中的数据,而不是每次都从注册表中读取。调用 update 函数会更新注册表和内存中缓存。

如果无法建立协调设置更改的机制,则可以通过 RegNotifyChangeKeyValue 函数设置更改通知,以便在值更改时收到通知。一般原则是,应该尽可能针对常见情况进行优化,而不是针对罕见情况进行优化。常见情况是注册表值未更改。通过使用通知机制,可以将“但是如果值更改了怎么办?”的成本从内部循环中移出,并转移到大多数时间不执行的代码中。(请记住,最快的代码是永远不会运行的代码。)

当然,你不想在一个线程上等待多个通知事件。我的方法是:使用线程池。

RegisterWaitForSingleObject 函数可以用来告诉线程池,”嘿,当这个对象发出信号时,请通知我。” 然后,线程池会将其与要求等待的所有其他句柄组合成一个巨大的 WaitForMultipleObjects 调用。这样,一个线程可以处理多个等待对象。

需要注意的一个地方是,RegNotifyChangeKeyValue 函数所发出的通知具有线程亲缘性。
如果调用 RegNotifyChangeKeyValue 函数的线程退出,则会引发通知。这意味着你不应该从线程池线程调用该函数,因为当工作列表空闲并且不再需要它们存在时,系统将销毁线程池中的线程。

如果你不小心搞砸了并从线程池线程调用它,你会发现当线程池清理代码运行时,事件不断虚假触发,这可不是一件好事。

相反,你应该从持久线程(例如,实际关心值的线程) 创建等待,并在那里注册等待。当事件在线程池上触发时,处理更改,然后要求持久线程启动 RegNotifyChangeKeyValue 的新周期。这样,事件始终与持久线程相关联,而不是与暂时性线程池线程相关联。

总结

一般我们会将应用程序的设置数据保存到注册表,这很方便,但是记得读取的时候,尽量只读一次并缓存结果,而不是每次都从注册表里读取,这对运行时性能是有伤害的。

最后

Raymond Chen的《The Old New Thing》是我非常喜欢的博客之一,里面有很多关于Windows的小知识,对于广大Windows平台开发者来说,确实十分有帮助。
本文来自:《The performance cost of reading a registry key》

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/697118.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

1 Prometheus-监控简介

目录 1 什么是监控 1.1 技术作为客户 1.2 业务作为客户 2. 监控基础知识 2.1 事后监控 2.2 机械式/模板式/无脑式监控 2.3 不够准确的监控 2.4 静态监控 2.5 不频繁的监控 2.6 缺少自动化或操作繁琐/不便 2.7 监控模式总结 3.监控机制 3.1 探针和内省 3.2 拉取和推…

视觉大模型应该长什么样

背景 最近朋友圈一直可以看到一个论调,视觉没有一个chatgpt一样强大的模型。似乎确实如此,视觉确实是缺一个通用能力的大模型;有些小伙伴可能就会讲了数据怎么能讲没有大模型:diffusion、della、muse、sam、controlnet一堆的大模…

springboot在启动时做点什么

Component public class ApplicationInitListener implements ApplicationListener<ContextRefreshedEvent> {Overridepublic void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {System.out.println("ContextRefreshedEvent.....容器初始化完…

Java 集合继承关系图

Java 容器类库的用途是“保存对象”&#xff0c;并划分为两大类,序列Collection和健值对 Map Collection接口&#xff1a;一个独立元素的序列&#xff0c;衍生的2个子类接口 List接口&#xff1a;存储有序的、可重复的数据 实现类: ArrayList、LinkedList、Vector Set接口&am…

SSMP整合案例(9) 统一表现层数据返回格式

上文 SSMP整合案例(8) Restful开发表现层接口 我们就已经是把表现层的接口写完了 但是 我们会发现 现在前端人员拿到我们的数据 格式看着非常的乱 我们 数据库 添加 修改 删除 就是但数据的格式 一个 布尔值 查询 就是 查多个 一个集合 查询 全部 则就是 一个对象的格式 还有分…

Linux 学习记录41(C++篇)

Linux 学习记录41(C篇) 本文目录 Linux 学习记录41(C篇)一、C中的引用1. 引用的定义2. 引用的注意事项3. 引用的基本使用4. 引用作为函数的入口参数5. 引用作为函数的返回值6. 常引用7. 结构体引用8. 指针和引用的区别 二、C中的动态内存分配1. new关键字(1. 申请单个类型的空间…

AI建模工具对比:如何选择适合你的工具套件

在人工智能&#xff08;AI&#xff09;的浪潮下&#xff0c;越来越多的企业和科研机构开始应用AI技术进行建模和分析。然而&#xff0c;选择哪种AI建模工具套件一直是一个让人挠头的问题。市面上存在着众多的AI建模工具&#xff0c;它们各有特点和优势&#xff0c;但如何找到适…

SpringBoot启动失败,也不报错

1&#xff09;将启动类添加try-catch捕获信息 在springboot的启动类中添加try-catch即可出现具体错误信息&#xff1b; try {SpringApplication.run(ConverterApplication.class, args);} catch (Exception e) {System.out.println("e.getMessage() " e.getMessage…

海运费查询:了解国际海运费的方法与注意事项

国际贸易中&#xff0c;海运是一种常见的货物运输方式。而对于企业或个人来说&#xff0c;了解和查询国际海运费是非常重要的。本文将介绍一些查询国际海运费的方法和注意事项&#xff0c;帮助您更好地掌握海运费用信息。 一、国际海运费的计算方法 FCL&#xff08;整箱&#…

祖冲之算法

祖冲之算法 1.题目描述 π 3.1415926~3.1415927之间 4/1-4/34/5-4/74/9-4/114/13.......... 通过关系,来计算 运算多少次之后,才会得到3.1415926~3.1415927之间2.代码 public class Main2 {public static void main(String[] args) {double ltargetPi3.1415926;double rtarg…

两两交换链表中的节点(LeetCode 24)

题目 24. 两两交换链表中的节点 思路 最开始自己画&#xff0c;越画越复杂比较复杂&#xff0c;写不出来&#xff01;&#xff08;呜呜&#xff09;去看了解题思路&#xff0c;发现只需要三步。&#xff0c;按以下思路写了代码&#xff0c;循环停止那里的条件我还以有更好的写…

android逆向开发之Frida逆向基础

Frida是一款功能强大的动态分析和逆向工程工具&#xff0c;可用于在运行时修改和监控应用程序。它支持多个平台&#xff0c;包括Android、iOS、Windows、macOS等&#xff0c;提供了JavaScript API&#xff0c;使用户能够在目标应用程序中直接执行自定义的脚本代码。 基础知识 …

CSS_高度自动过渡 auto height

方法一 grid 布局中的 fr 单位&#xff08;推荐使用&#xff09; <div class"wrap"><button class"trigger">鼠标放上来试试</button><div class"grid"><div><p>高度自动过渡</p></div></d…

leedcode-只出现一次的数字-异或

题目 题目 代码 class Solution { public:int singleNumber(vector<int>& nums) {int ansnums[0];for(int i1;i<nums.size();i){ansans^nums[i];}return ans;} };

【力扣】144、二叉树的前序遍历

力扣、144 给你二叉树的根节点 root &#xff0c;返回它节点值的 前序 遍历。 // 递归遍历 var preorderTraversal function(root){let arr [];var fun &#xff08;node&#xff09;>{if(node){//先根节点&#xff1a;arr.push(node.val);fun(node.left);//遍历左子树…

IT必备的技能,看看你掌握了吗?

目录 架构知识技术与业务场景的结合数据库知识操作系统知识网络知识存储知识云计算知识编程语言知识软件产品知识硬件知识信息安全知识IT前沿技术知识。 今天在看一本书叫做《一本书讲透售前》&#xff0c;这本书分为了两部分&#xff1a; 第一部分描述了售前的工作篇&#xff…

Python图像高光调整

看了这个文章&#xff0c;里面有专门的c的实现&#xff0c;我这边简单的使用python进行了实现&#xff0c;实现了两个版本&#xff0c;一个是python遍历像素&#xff0c;一个是使用numpy加速&#xff0c;代码如下&#xff1a; import time import numpy as np import cv2def l…

软考高级系统架构设计师(六) 企业应用集成电子商务

目录 企业应用集成(重点) 电子商务 企业应用集成(重点) ps: 数据集成&#xff0c;比如 数据中间件 业务流程集成&#xff1a;过程集成&#xff0c;B2B--企业之间 企业门户&#xff1a; ps: 重构需求 电子商务

在教育领域中使用ChatGPT有哪些优点?

人工智能在教育领域的应用正在迅速增加。OpenAI于2022年11月开发的聊天机器人ChatGPT在全球范围内广受欢迎。 由于其受欢迎程度以及生成类似人类问题的回答的能力&#xff0c;ChatGPT正在成为许多学习者和教育工作者值得信赖的伴侣。然而&#xff0c;与任何新兴技术一样&#x…

机器学习——Word2Vec

参考资料&#xff1a; https://zhuanlan.zhihu.com/p/114538417https://www.cnblogs.com/pinard/p/7243513.html 1 背景知识 1.1 统计语言模型 统计语言模型是基于语料库构建的概率模型&#xff0c;用来计算一个词串 W ( w 1 , w 2 , ⋯ , w T ) W(w_1,w_2,\cdots,w_T) W…