翻译《The Old New Thing》 - The performance cost of reading a registry key

2024-05-10 16:28

本文主要是介绍翻译《The Old New Thing》 - The performance cost of reading a registry key,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

The performance cost of reading a registry key - The Old New Thing (microsoft.com)icon-default.png?t=N7T8https://devblogs.microsoft.com/oldnewthing/20060222-11/?p=32193

Raymond Chen 2006年2月22日


读取注册表键的性能成本

        注册表是一个方便的场所,它以统一且多线程安全的方式记录了跨进程的持久数据。如果将数据存储在 HKEY_CURRENT_USER 下,它还可以随用户漫游,并且即使在不支持安全性的FAT文件系统上,也可以对单个键进行安全设置。

        但这并不意味着它是零成本的。打开一个键、读取一个值、然后关闭它的操作大约需要60,000到100,000个CPU周期(据我了解)。这是在假设你访问的键已经在缓存中的情况下。如果你保持键打开的状态,那么读取值的操作成本会降低到大约15,000到20,000个CPU周期。(这些数字是基于Windows XP的估算;实际的性能可能有所不同。)

        因此,你不应该在程序的核心循环中读取注册表键。这不仅会在查询时消耗CPU时间,而且频繁地访问注册表意味着用于定位和存储你的键的数据结构(包括注册表缓存中的条目)会被保留在系统的活动工作集中。不要在每次鼠标移动事件中都读取注册表键;你应该一次性读取值并将其缓存起来。如果你担心程序运行期间有人更改了该值,你可以建立一个协议,让人们在想要更改设置时遵循。例如,Windows使用如 SystemParametersInfo 这样的函数来操作那些通常被缓存而不是每次需要时都直接从注册表中读取的设置。调用更新函数可以同时更新注册表和内存中的缓存。

        在可能的情况下,应该针对常见情况进行优化,而不是罕见情况。常见情况是注册表的值没有变化。通过使用通知机制,你可以将“如果值改变了怎么办?”的成本从核心循环中转移出去,转移到大多数时候不会执行的代码中。(记住,最快的代码是没有运行的代码。)

        当然,你不会希望让一个线程一直等待通知事件。我建议使用线程池。RegisterWaitForSingleObject 函数允许你向线程池发出请求:“嘿,当这个对象被触发时,请呼叫我,好吗?”线程池随后会将这个请求与其他所有它被要求等待的句柄结合起来,统一进行 WaitForMultipleObjects 调用。这样,一个线程就可以同时处理多个等待事件。

        使用 RegNotifyChangeKeyValue 函数时需要注意的一点是,通知具有线程亲和性!如果调用 RegNotifyChangeKeyValue 函数的线程终止,通知将被激发。这意味着你不应该从线程池中的线程调用此函数,因为系统会在线程池的工作列表空闲且不再需要时销毁线程。如果你错误地从线程池线程调用它,你会发现事件会不断地错误触发,因为线程池的清理代码在运行,这可能使问题变得更糟!相反,你应该从一个持久的线程(比如,真正关心该值的线程)创建等待,并在那里注册等待。当线程池中的事件触发时,处理更改,然后让你的持久线程启动 RegNotifyChangeKeyValue 的新周期。这样一来,事件总是与你持久的线程相关联,而不是与临时的线程池线程相关联。

这篇关于翻译《The Old New Thing》 - The performance cost of reading a registry key的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


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

相关文章

SQL 外键Foreign Key全解析

《SQL外键ForeignKey全解析》外键是数据库表中的一列(或一组列),用于​​建立两个表之间的关联关系​​,外键的值必须匹配另一个表的主键(PrimaryKey)或唯一约束(UniqueCo... 目录1. 什么是外键?​​ ​​​​2. 外键的语法​​​​3. 外键的约束行为​​​​4. 多列外键​

浅谈Redis Key 命名规范文档

《浅谈RedisKey命名规范文档》本文介绍了Redis键名命名规范,包括命名格式、具体规范、数据类型扩展命名、时间敏感型键名、规范总结以及实际应用示例,感兴趣的可以了解一下... 目录1. 命名格式格式模板:示例:2. 具体规范2.1 小写命名2.2 使用冒号分隔层级2.3 标识符命名3. 数据类型扩展命

Redis 热 key 和大 key 问题小结

《Redis热key和大key问题小结》:本文主要介绍Redis热key和大key问题小结,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录一、什么是 Redis 热 key?热 key(Hot Key)定义: 热 key 常见表现:热 key 的风险:二、

redis过期key的删除策略介绍

《redis过期key的删除策略介绍》:本文主要介绍redis过期key的删除策略,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录第一种策略:被动删除第二种策略:定期删除第三种策略:强制删除关于big key的清理UNLINK命令FLUSHALL/FLUSHDB命

Python中的魔术方法__new__详解

《Python中的魔术方法__new__详解》:本文主要介绍Python中的魔术方法__new__的使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、核心意义与机制1.1 构造过程原理1.2 与 __init__ 对比二、核心功能解析2.1 核心能力2.2

Java枚举类实现Key-Value映射的多种实现方式

《Java枚举类实现Key-Value映射的多种实现方式》在Java开发中,枚举(Enum)是一种特殊的类,本文将详细介绍Java枚举类实现key-value映射的多种方式,有需要的小伙伴可以根据需要... 目录前言一、基础实现方式1.1 为枚举添加属性和构造方法二、http://www.cppcns.co

MySQL中Next-Key Lock底层原理实现

《MySQL中Next-KeyLock底层原理实现》Next-KeyLock是MySQLInnoDB存储引擎中的一种锁机制,结合记录锁和间隙锁,用于高效并发控制并避免幻读,本文主要介绍了MySQL中... 目录一、Next-Key Lock 的定义与作用二、底层原理三、源代码解析四、总结Next-Key L

Python中__new__()方法适应及注意事项详解

《Python中__new__()方法适应及注意事项详解》:本文主要介绍Python中__new__()方法适应及注意事项的相关资料,new()方法是Python中的一个特殊构造方法,用于在创建对... 目录前言基本用法返回值单例模式自定义对象创建注意事项总结前言new() 方法在 python 中是一个

深入理解Redis大key的危害及解决方案

《深入理解Redis大key的危害及解决方案》本文主要介绍了深入理解Redis大key的危害及解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着... 目录一、背景二、什么是大key三、大key评价标准四、大key 产生的原因与场景五、大key影响与危

Golan中 new() 、 make() 和简短声明符的区别和使用

《Golan中new()、make()和简短声明符的区别和使用》Go语言中的new()、make()和简短声明符的区别和使用,new()用于分配内存并返回指针,make()用于初始化切片、映射... 详细介绍golang的new() 、 make() 和简短声明符的区别和使用。文章目录 `new()`