- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在为我的一个类(class)编写一个文件系统。这个函数大大降低了我的性能,我不明白为什么。我盯着这段代码看的时间太长了,我可能遗漏了一些非常明显的东西。有人明白为什么这个功能运行得这么慢吗?
int getFreeDataBlock(struct disk *d, unsigned int dataBlockNumber)
{
if (d == NULL)
{
fprintf(stderr, "Invalid disk pointer to getFreeDataBlock()\n");
errorCheck();
return -1;
}
// Allocate a buffer
char *buffer = (char *) malloc(d->blockSize * sizeof(char));
if (buffer == NULL)
{
fprintf(stderr, "Out of memory.\n");
errorCheck();
return -1;
}
do {
// Read a block from the disk
diskread(d, buffer, dataBlockNumber);
// Cast to appropriate struct
struct listDataBlock *block = (struct listDataBlock *) buffer;
unsigned int i;
for (i = 0; i < DATABLOCK_FREE_SLOT_LENGTH; ++i)
{
// We are in the last datalisting block...and out of slots...break
if (block->listOfFreeBlocks[i] == -2)
{
break;
}
if (block->listOfFreeBlocks[i] != -1)
{
int returnValue = block->listOfFreeBlocks[i];
// MARK THIS AS USED NOW
block->listOfFreeBlocks[i] = -1;
diskwriteNoSync(d, buffer, dataBlockNumber);
// No memory leaks
free(buffer);
return returnValue;
}
}
// Ok, nothing in this data block, move to next
dataBlockNumber = block->nextDataBlock;
} while (dataBlockNumber != -1);
// Nope, didn't find any...disk must be full
free(buffer);
fprintf(stderr, "DISK IS FULL\n");
errorCheck();
return -1;
}
正如您从 gprof 中看到的那样,diskread()
和 diskwriteNoSync()
都占用了大量时间?
% cumulative self self total
time seconds seconds calls ms/call ms/call name
99.45 12.25 12.25 2051 5.97 5.99 getFreeDataBlock
0.24 12.28 0.03 2220903 0.00 0.00 diskread
0.24 12.31 0.03 threadFunc
0.08 12.32 0.01 2048 0.00 6.00 writeHelper
0.00 12.32 0.00 6154 0.00 0.00 diskwriteNoSync
0.00 12.32 0.00 2053 0.00 0.00 validatePath
还是我没有正确理解输出?
感谢您的帮助。
最佳答案
您一直盯着这段代码并对 gprof
输出感到困惑这一事实让您成为了好伙伴,因为 gprof
和它教授的概念仅适用于没有 I/O 的小型学术规模程序。 Here's the method I use.
一些有用的帖子的摘录已被删除,给出了一些关于分析的神话:
程序计数器采样很有用。
它只有在你有一个不必要的热点瓶颈时才有用,比如大量标量值的冒泡排序。例如,一旦将其更改为使用字符串比较的排序,它仍然是一个瓶颈,但程序计数器采样不会看到它,因为现在热点在字符串比较中。另一方面,如果要对 extended 程序计数器(调用堆栈)进行采样,则会清楚地显示调用字符串比较的点(排序循环)。 事实上,gprof 试图弥补仅 pc 采样的局限性。
阻塞时不需要采集样本
这个神话的原因有两个:1)当程序等待时 PC 采样是没有意义的,以及 2)对计时准确性的关注。然而,对于 (1),程序很可能正在等待它请求的某些东西,例如文件 I/O,您需要知道,以及哪些堆栈示例显示。 (很明显,您希望在等待用户输入时排除样本。)对于 (2),如果程序只是因为与其他进程竞争而等待,那么它可能在运行时以相当随机的方式发生。因此,虽然程序可能需要更长的时间,但这不会对重要的统计数据产生很大影响,即语句在堆栈上的时间百分比。
语句或函数调用的计数很有用。
假设您知道某个函数已被调用 1000 次。你能从中看出它花费了多少时间吗?您还需要知道平均运行需要多长时间,将其乘以计数,然后除以总时间。平均调用时间可能从纳秒到秒不等,因此仅靠计数并不能说明什么。如果有堆栈样本,则例程或任何语句的成本只是它所在的样本的一小部分。如果可以使例程或语句不花时间,那么这部分时间原则上可以节省整个时间,因此这是与性能最直接的关系。
还有更多的来源。
关于c - 功能运行太慢......我不明白为什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20308078/
我正在构建一个 RCP 应用程序,其中每个季度都会更新功能/插件。因此,如果用户选择自动更新功能/插件,则会下载更新插件的新 jar,但旧插件仍在使用我不再使用的磁盘空间。 我厌倦了删除包含旧 jar
我如何从外部 Controller 功能中调用 Controller 内部的功能,例如电话间隙回调功能 这是 Controller 外部定义的功能 function onDeviceReady()
如果某个功能(例如 MediaSource)可用,我如何使用 Google Dart 检查。 new MediaSource() 抛出一个错误。如何以编程方式检查此类或功能是否存在?有任何想法吗?是否
我正在尝试运行 Azure Orchestrations,突然我开始从 statusQueryGetUri 收到错误: 协调器函数“UploadDocumentOrchestrator”失败:函数“U
我见过 iPhone 上的应用程序,如果在 3.0 上运行,将使用 3.0 功能/API,例如应用内电子邮件编辑器,如果在 2.x 上运行,则不使用这些功能,并退出应用程序以启动邮件相反。 这是怎么做
这是 DB 规范化理论中的一个概念: Third normal form is violated when a non-key field is a fact about another non-ke
如果我定义 #if SOMETHING #endif 而且我还没有在任何地方定义 SOMETHING。 #if 中的代码会编译吗? 最佳答案 当#if的参数表达式中使用的名称未定义为宏时(在所有其他宏
我刚刚澄清了 A* 路径查找应该如何在两条路径具有相等值的 [情况] 下运行,无论是在计算期间还是在结束时,如果有两条相等的短路径。 例如,我在我的起始节点,我可以扩展到两个可能的节点,但它们都具有相
Java有没有类似下面的东西 宏 一种遍历所有私有(private)字段的方法 类似于 smalltalk symbols 的东西——即用于快速比较静态字符串的东西? 请注意,我正在尝试为 black
这个程序应该将华氏度转换为摄氏度: #include int main() { float fahrenheit, celsius; int max, min, step;
当打开PC缓存功能后, 软件将采用先进先出的原则排队对示波器采集的每一帧数据, 进行帧缓存。 当发现屏幕中有感兴趣的波形掠过时, 鼠标点击软件的(暂停)按钮, 可以选择回看某一帧的波形
我有一个特殊的(虚拟)函数,我想在沙盒环境中使用它: disable.system.call eval(parse(text = 'model.frame("1 ~ 1")'), envir = e
使用新的 Service 实现,我是否必须为我的所有服务提供一个 Options 方法? 使用我的所有服务当前使用的旧 ServiceBase 方法,OPTIONS 返回 OK,但没有 Access-
我正在阅读 Fogus 的关于 Clojure 的喜悦的书,在并行编程章节中,我看到了一个函数定义,它肯定想说明一些重要的事情,但我不知道是什么。此外,我看不到这个函数有什么用 - 当我执行时,它什么
我有大量的 C 代码,大部分代码被注释掉和/或 #if 0。当我使用 % 键匹配 if-else 的左括号和右括号时,它也匹配注释掉的代码。 有没有办法或vim插件在匹配括号时不考虑注释掉或#if 0
我有这个功能: map(map(fn x =>[x])) [[],[1],[2,3,4]]; 产生: val it = [[],[[1]],[[2],[3],[4]]] 我不明白这个功能是如何工作的。
我使用 Visual Studio 代码创建了一个函数应用程序,然后发布了它。功能应用程序运行良好。我现在在功能门户中使用代码部署功能(KUDU)并跳过构建。下面是日志 9:55:46 AM
我有一个数据框df: userID Score Task_Alpha Task_Beta Task_Charlie Task_Delta 3108 -8.00 Easy Easy
我真的无法解决这个问题: 我有一个返回数据框的函数。但是,数据框仅打印在我的控制台中,尽管我希望将其存储在工作空间中。我怎样才能做到这一点? 样本数据: n <- 32640 t <- seq(3*p
有没有办法找出所有可能的激活器命令行选项? activator -help仅提供最低限度的可用选项/功能列表,但所有好的东西都隐藏起来,即使在 typesafe 网站在线文档中也不可用。 到目前为止,
我是一名优秀的程序员,十分优秀!