构建哈希图的哈希图

2023-12-31

我不经常问问题(大多数时候问题可以通过一些研究来解决,对吧?)但我只是想听听你的意见,因为可能有更好的(更有效的方法来做到这一点)。

让我们看看,下面的代码工作得很好并且达到了它的目的。代码的结果是哈希图的哈希图,我需要它作为另一项工作的查找表。

背景:

  • $ccDb是一个由大约 200k 项组成的数组,属性为companyCd, costCenterNbr, costCenterShortNm, costCenterLongDescr.
  • 每个属性都必须被修剪(请不要让我修剪我的 Db,遗憾的是我不能)。
  • costCenterNbr包含在companyCd, 意思是每个companyCd可以有多个costCenterNbr.
  • companyCd可以包含 X 数量的costCenterNbr.
  • costCenterNbr具有独特的价值,同样companyCd.
  • costCenterShortNm and costCenterLongDescr相关于costCenterNbr

问题:

该映射必须在每次运行脚本时构建,因为信息是从 SQL 表(一直在变化)中获取的。构建这张地图大约需要 15 分钟(在一个相当好的服务器上,2CPU 12 核)。

问题:

您是否认为可以改进此代码以实现更快/更高效的执行?

$ccMap=@{}

foreach($line in $ccDb)
{
    $companyCd=$line.companyCd.trim()
    $costCenterNbr=$line.costCenterNbr.trim()
    $costCenterShortNm=$line.CostCenterShortNm.trim()
    $costCenterLongDescr=$line.CostCenterLongDescr.trim()
    
    $coceMap=@{
        $costCenterNbr=@{
            shortDesc=$costCenterShortNm
            longDesc=$costCenterLongDescr
        }
    }
    
    if($ccMap.ContainsKey($companyCd))
    {
        $ccMap[$companyCd]+=$coceMap
    }
    else
    {
        $ccMap.Add($companyCd,$coceMap)
    }
}

对于这么长的解释,我感到很抱歉,但我觉得最好预先提供最多的信息。很感谢任何形式的帮助。此外,我知道 PowerShell 对于我正在做的事情来说是一种非常糟糕的语言,而 C# 可能会更高效,但事实就是如此。

编辑:添加测量值以供参考。

Edit:

非常感谢@Mathias R. Jessen,这是他的代码的测量结果。优秀的代码。


不要使用+=紧密循环

这是你最大的水槽:

    $ccMap[$companyCd] += $coceMap

当您使用一个哈希表添加到另一个哈希表时+ (or +=就此而言),PowerShell 创建一个全新的哈希表:

# Create two different hashtables
$A = @{ Key1 = 'Value1' }
$B = @{ Key2 = 'Value2' }

# Let's save a second reference to the first table
$remember = $A

# Now let's use += to merge the two:
$A += $B

运行这个你会发现$B and $remember没有变化,但是$A拥有两把钥匙 - 因此必须是一把新钥匙。

为了解决这个性能损失,请跳过构建$coceMap完全,并颠倒顺序(如果不存在,则先构造哈希表,然后分配):

$ccMap=@{}

foreach($line in $ccDb)
{
    $companyCd=$line.companyCd.trim()
    $costCenterNbr=$line.costCenterNbr.trim()
    $costCenterShortNm=$line.CostCenterShortNm.trim()
    $costCenterLongDescr=$line.CostCenterLongDescr.trim()

    # Create new hashtable if none exist, otherwise retrieve the existing one
    if($ccMap.ContainsKey($companyCd))
    {
        $coceMap = $ccMap[$companyCd]
    }
    else
    {
        $coceMap = $ccMap[$companyCd] = @{}
    }
    
    $coceMap[$costCenterNbr] = @{
        shortDesc=$costCenterShortNm
        longDesc=$costCenterLongDescr
    }
}

标杆管理+=

下面是一个简化的示例,显示了 10000 个具有 50 个不同键的项目的差异:

$data = @(
    1..10000 |Select-Object @{Name='Company';Expression={Get-Random -Maximum 50}},@{Name='CostCenter';Expression={Get-Random}}
)

@(
    Measure-Command {
        $map = @{}

        foreach($line in $data){
            $entry = @{
                $line.CostCenter = @{
                    Value = 123
                }
            }

            if($map.ContainsKey($line.Company)){
                $map[$line.Company] += $entry
            }
            else {
                $map[$line.Company] = $entry
            }
        }
    }

    Measure-Command {
        $map = @{}

        foreach($line in $data){
            if($map.ContainsKey($line.Company)){
                $entry = $map[$line.Company]
            }
            else {
                $entry = $map[$line.Company] = @{}
            }

            $entry[$line.CostCenter] = @{
                Value = 123
            }
        }
    }
) |select TotalMilliseconds

在我的笔记本电脑上给出:

TotalMilliseconds
-----------------
         306.4218
          47.8164

一般来说,如何识别这样的时间沉降?

有多种方法可以分析 PowerShell 的运行时行为,但这是我个人的首选:

  1. Install PSProfiler https://www.powershellgallery.com/packages/PSProfiler (Disclaimer: I'm the maintainer of PSProfiler):
    • Install-Module PSProfiler -Scope CurrentUser
  2. Use Measure-Script就像你一样Measure-Command:
Measure-Script {
    $map = @{}

    foreach($line in $data){
        $entry = @{
            $line.CostCenter = @{
                Value = 123
            }
        }

        if($map.ContainsKey($line.Company)){
            $map[$line.Company] += $entry
        }
        else {
            $map[$line.Company] = $entry
        }
    }
}
  1. 等待代码完成
  2. 查看输出:

    Anonymous ScriptBlock


      Count  Line       Time Taken Statement
      -----  ----       ---------- ---------
          0     1    00:00.0000000 {
          1     2    00:00.0000187     $map = @{}
          0     3    00:00.0000000
          0     4    00:00.0000000     foreach($line in $data){
      10000     5    00:00.0635585         $entry = @{
          0     6    00:00.0000000             $line.CostCenter = @{
          0     7    00:00.0000000                 Value = 123
          0     8    00:00.0000000             }
          0     9    00:00.0000000         }
          0    10    00:00.0000000
          0    11    00:00.0000000         if($map.ContainsKey($line.Company)){
       9950    12    00:00.3965227             $map[$line.Company] += $entry
          0    13    00:00.0000000         }
          0    14    00:00.0000000         else {
         50    15    00:00.0002810             $map[$line.Company] = $entry
          0    16    00:00.0000000         }
          0    17    00:00.0000000     }
          0    18    00:00.0000000 }

观察第 12 行占用的总执行时间最多 - 明显多于其他任何行:

       9950    12    00:00.3965227             $map[$line.Company] += $entry
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

构建哈希图的哈希图 的相关文章

  • 使用 powershell 从 Tfs 获取工作项存储

    如何使用 powershell 从 TFS 获取 WorkItemStore 我尝试过以下方法 function get tfs param string ServerName http MyServer 8080 tfs begin pr
  • 将子进程的输出重定向到父进程 - Powershell

    我有 powershell 进程 并且我正在调用 Start Process 或 System Diagnostic Process 以作为不同用户启动子进程 以获取其他用户环境变量 我尝试使用重定向输出 但它不起作用 下面是代码 proc
  • 输入编码:接受UTF-8

    我需要在 PowerShell 下获取本机应用程序的输出 问题是 输出是用 UTF 8 无 BOM 编码的 PowerShell 无法识别它 只是将那些时髦的 UTF 字符直接转换为 Unicode 我发现 PowerShell 有 Out
  • 使用 ICACLS 将文件权限设置为“只读”[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我很难从简单 直观的方式转变过来chmod 400尝试在 Windows 命令提示符中执行相同的操作ICACLS 与 UNIX LINUX
  • Copy-Item 将目录及其内容复制到 UNC 路径

    我正在尝试使用 PowerShell 1 0 获取文件夹的内容并将其复制到另一个文件夹 非常简单的东西 使用起来一切都很好Copy Item from to recurse如果我从本地文件夹复制到本地文件夹 然而 如果 to变量是一个UNC
  • 在 Powershell 中获取小文件的“磁盘大小”

    我正在使用一个遗留系统 该系统有大量来自外部系统的导入 其中大多数通过下载文件 根据上下文大小不同 处理它 然后将文件存储在 SAN 卷上的其他位置 格式为 NTFS 和安装在 WS2008R2 盒子上 我们遇到的问题是 由于簇的大小 大量
  • 基于团体成员资格的额外输出

    我希望你们都度过愉快的一天 如果这是一个糟糕的问题尝试 我提前道歉 我不太擅长这个 介绍 首先 我想介绍一下我实际正在创作的内容 我为 MSP 工作 我的任务是创建一个供我们的一位客户使用的用户管理 Powershell 脚本 以便我们可以
  • 在 Windows powershell 中选择下拉列表中的 Web ui 测试自动化选项

    抱歉 如果这个问题太简单了 但我对 Windows Powershell 相当陌生 我看过的所有下拉列表教程都向您展示了如何向用户显示下拉列表 无论如何 我想做的是使用 Powershell 测试我的 Web 应用程序 我需要将下拉列表更改
  • Powershell:使用变量引用脚本块中 $_ 的属性

    var id 1 name abc age 1 id 2 name def age 2 properties ID Name Age format foreach p in properties format label p Express
  • 是否可以通过用户租户上的 ARM 模板在 Azure 上自动注册应用程序?

    我正在尝试通过 ARM 模板将解决方案部署为托管应用程序 为了使部署正常工作 我需要注册应用程序的客户端 ID 和客户端密钥以及租户 ID 在我之前的范围中 我假设用户将注册一个现有的应用程序 但现在我想为用户自动化应用程序注册过程 并能够
  • java 未知深度的嵌套哈希图

    我有一个要求 我需要有一个嵌套的哈希图 但深度将在运行时决定 例如 如果在运行时 用户说 3 那么我的哈希图应该是这样的 HashMap
  • 如何在 PowerShell 中将 5.7303333333e+02 等字符串转换为十进制?

    我正在尝试转换字符串 例如5 7303333333e 02 to the decimal类型 我尝试过使用 decimal TryParse但返回值是假的 有没有类似的方法 datetime parseexact 或任何干净的方法来转换这些
  • 用于按顺序批量重命名文件的 PowerShell 命令

    我正在尝试让最终用户更轻松地进行批处理文件命名 在拍摄外景时 我们有时只能拍摄 1 张照片或 500 张照片 具体取决于拍摄地点的大小 下面的代码可以很好地根据目录中的文件数量批量重命名我们的照片 prefix SomePrefix fil
  • powershell中的quser语言独立解析

    我想查询当前使用 powershell 登录到我的计算机的所有用户 我当前的解决方案如下所示 userObject quser server localhost 2 gt 1 ForEach Object Process replace s
  • Java中有没有办法随机获取HashMap的值?

    Java中有没有办法随机获取HashMap的值 这有效 Random generator new Random Object values myHashMap values toArray Object randomValue values
  • 使用带有等于和句点的单连字符参数执行外部命令

    我有一个接受这样的参数的工具 例如在test ps1 foo exe name john 因此 每个参数都用一个连字符指定 名称 等于 然后是参数的值 当我从 PowerShell 调用这个精确表达式时 它执行时没有任何问题 但是 当其中一
  • 在 PowerShell 中按列拆分文本

    我是一个 PowerShell 新手 通常是 Bash 目前正在尝试获取 qwinsta 输出以显示谁以 rdpwd rdesktop 用户身份登录 以便我可以根据用户名列表检查每个用户名 如果它们不匹配 请将其注销 我目前正在解决两个问题
  • Azure DevOps - 在 PowerShell 脚本中设置和使用变量

    我有一个 Azure DevOps 构建管道 其中有两个单独的 PowerShell 脚本 在第一个脚本中 我从 XML 文件中获取一个值 并将该值设置在环境变量中 在我的第二个脚本中 我想使用环境变量中的值 不幸的是 我没有看到环境变量被
  • 如何使用个人访问令牌对 Visual Studio Team Services 和 Team Foundation Server 进行身份验证?

    在 PowerShell 中 如何使用个人访问令牌 PAT 对我的 Visual Studio Team Services VSTS 帐户或本地 Team Foundation Server TFS 进行身份验证 截至 2015 年 7 月
  • Java 8 哈希映射无法正常工作

    自 java 8 以来 我们面临着 HashMap 行为方式的奇怪问题 当HashMap的键实现了Comparable接口 但compareTo的实现与equals不一致时 HashMaps 长得比它们应该长的大得多 它们包含多个相同元素的

随机推荐

  • ggplot2中密度曲线下的阴影面积

    我已经绘制了一个分布 我想对 gt 95 的区域进行着色 但是 当我尝试使用此处记录的不同技术时 ggplot2 按组密度曲线下的阴影面积 https stackoverflow com questions 20355849 ggplot2
  • 在Windows 7中运行MinGW gcc编译器,无需设置环境变量

    我在 Windows 中有一个 MinGW 文件夹 但没有在环境变量中设置任何路径 当我运行以下命令时 D toolchains MinGW bin gt gcc exe hw c o hw 我收到这个错误 gcc exe error Cr
  • Yii2 GridView实现外部表相关表的值过滤和排序

    我有 3 张表 CREATE TABLE tabCve intCveID INTEGER NOT NULL AUTO INCREMENT strNumber VARCHAR 20 NOT NULL fltScore FLOAT 0 strD
  • Postgres 9.4 在刷新物化视图期间挂起

    我正在考虑 Postgres 9 4 中物化视图的问题 有时查询 刷新物化视图xxx 会永远挂起 我发现的唯一方法是完全重新启动 postgres 服务 重新启动后执行需要几秒钟 我的视图并不复杂 大约使用 10 个表 我已经执行了sele
  • 显示 W3C 合规性

    我认为大多数人都同意遵守 W3C 标准是值得追求的 但是 您是否宣传您的网站合规这一事实 这样做有积极的一面还是消极的一面 如果你确实表现出你的顺从 你会怎样做 我不知道 因为普通用户不知道网站 有效 意味着什么 如果关心此类事情的人感兴趣
  • 强制带注释的类包含带注释的字段

    是否可以强制 在编译时 带注释的类具有带注释的字段 我有这个注释 Target value ElementType TYPE interface MyClass Target value ElementType FIELD interfac
  • ASP.Net Core 2.1 注册自定义ClaimsPrincipal

    我正在创建一个 Windows 身份验证应用程序 但角色位于自定义数据库中而不是 AD 上 因此我创建了一个自定义 ClaimsPrincipal 来覆盖通常在 AD 中查找角色的 User IsInRole 函数 但是 在运行应用程序时
  • 如何使用带有多个参数的 Flask Jinja2 url_for

    我在使用时遇到问题jinja2 url for 功能 我有这样的路线 app route article
  • 使用 VBA 将字段添加到 MS Access 表

    我需要将计算字段添加到现有表中 我知道有两种方法可以做到这一点 我想知道是否有人对哪种方法最好以及如何使它们发挥作用有任何意见 使用 TableDef CreateField 然后使用 TableDef Fields Append 使用 D
  • Jenkins 在参数上跳过 SCM

    有谁知道如何使作业跳过命令 参数 上的 SCM 步骤 我希望能够触发作业并使用现有视图 在我的例子中为 ClearCase 但可以是 SVN 工作副本 来运行构建 这样做的动机是为了节省时间 我的 ClearCase 视图需要大约 20 分
  • C++ 控制台输入块,所以我无法杀死线程

    我的程序有许多不同的线程处理不同的事情 其中 之一处理用户输入 其他线程没有太多阻止调用的方式 而那些阻止的线程是基于网络的 因此当套接字关闭时将被中断或正常返回 然而 用户线程调用std cin以获取用户输入 这样做的效果是 当所有其他线
  • 红宝石信号量?

    我正在研究用 Ruby 实现 Fair Barbershop 问题 这是课堂作业 但我不是在寻找任何讲义 我一直在疯狂地搜索 但我似乎无法找到反映 C 中信号量的 Ruby 实现 我知道有 Mutex 这很棒 单一实现 完全完成了那种信号量
  • @Startup @Singleton 在 WebLogic (EJB 3.1) 中实例化两次

    我有一个班级标记 Startup and Singleton并且构造函数被调用两次 为什么会被调用两次 WebLogic 12 1 1 本地运行 非集群 PostConstruct 存在时也会被调用两次 XML 配置中没有任何相关内容 we
  • 对向量进行回调的更简单方法(或者 STL 中的其他内容)? C++

    我正在制作一个简单的犯罪模拟游戏 在整个过程中 我不断地重复做同样的事情 vector
  • 如何修复“导入org.junit.jupiter”?

    我正在开发 MMU 项目 但我不知道如何修复此错误 Test注解 我该如何修复它 我已经添加了JUnit图书馆 但这不起作用 JUnit Jupiter 是 JUnit 5 的一部分 您很可能添加了旧版本的 JUnit 尤其是根据junit
  • Symfony 与多个主机匹配路由

    我知道可以按主机过滤路由 如下所示 irc backend report stacking issue path reports stacking issues host backend domain com defaults contro
  • 使用默认调试密钥库签名时抛出 SecurityException

    我收到了安全异常从昨天开始 我使用默认调试密钥库的签名保护级别来启动服务 奇怪的是 我在昨天之前没有收到此错误 并且我没有进行任何与安全相关的更改 另一方面 我自己的用于发布的密钥库仍然运行良好 有关的AndroidManifest xml
  • 在python中使用VTK找到3D空间中两个圆柱体的交集

    在 python 中使用 VTK 我编写了一些代码来为我想要的对象创建一个 actor 例如对于气缸 def cylinder object startPoint endPoint radius my color DarkRed USER
  • Xcode 4.5.1 存档时卡住

    我刚刚将我的 xcode 升级到版本 4 5 1 以前一切正常 但现在 当我存档项目时 xcode 卡住 挂起并且永远不会完成归档 在顶部的状态中 文字显示 编译 10 个源文件中的 10 个 之后什么也没有发生 它只是卡住了 我仍然可以编
  • 构建哈希图的哈希图

    我不经常问问题 大多数时候问题可以通过一些研究来解决 对吧 但我只是想听听你的意见 因为可能有更好的 更有效的方法来做到这一点 让我们看看 下面的代码工作得很好并且达到了它的目的 代码的结果是哈希图的哈希图 我需要它作为另一项工作的查找表