后来改进的debug.as,因为有个小bug会严重影响速度,详细见前文

本文介绍了一种优化Flash应用程序中日志记录系统的方法,通过改进textField对象的text属性操作及使用Array.join()方法来提高日志读取速度,使得处理大量日志文件时效率提升了两倍。

上一篇详细介绍debug.as的文章发了以后,发现一个小问题。因为对textField对象的text属性直接作+=操作会严重影响速度(这应该是flash的bug),故对代码作了些改进。改动主要在textField的onSetFocus()函数中。修正后读入日志速度比原来快了两倍。

另外用Array.join()方法替代了原来循环连接字符串的操作,比原有代码速度提高了一倍。

经过测试,在P4 2.4上,现在可以处理20多万行日志而不会弹出速度慢的警告窗口。

//Debug.as
//
written by foreverflying
//
class Debug
{
    
//=========================================================
    //in player trace===============================Version 1.2
    static public function CreateTrace( depth, x, y, width, height, lineCount, mc )
    
{
        
if( _logObj != undefined ){
            
return;
        }

        
if( mc == undefined ){
            mc 
= _level0;
        }

        
if( lineCount == undefined ){
            lineCount 
= 12;
        }

        _logObj 
= new Array();
        _logObj.allowChange 
= true;
        _logObj.isPart 
= false;
        _logObj.lineCount 
= lineCount;
        mc.createTextField( 
'__traceText__', depth, x, y, width, height );
        _logObj.traceText 
= mc['__traceText__'];
        
var traceText = _logObj.traceText;
        
var str = ' ';
        
while( traceText.maxscroll < 2 ){
            traceText.text 
= str;
            str 
+= str;
        }

        traceText.maxRow 
= traceText.bottomScroll - traceText.scroll + 1;
        traceText.text 
= '';
        traceText._visible 
= _traceVisible;
        traceText.border 
= true;
        traceText.background 
= true;
        traceText.backgroundColor 
= 0xFFFFFF;
        traceText.onSetFocus 
= function( oldFocus )
        
{
            _logObj.allowChange 
= false;
            
if!_logObj.isPart ){
                
return;
            }

            
if( _logObj[0== undefined ){
                
return;
            }

            
var s = _logObj[_logObj.length-1];
            s 
= s.charAt( s.length-1 );
            s 
= s == ' ' ? '' : ' ';
            
forvar i=0; i < this.maxRow - lineCount; i++ ){
                s 
+= ' ';
            }

            
this.text = _logObj.join( ' ' ) + s;
            _logObj.isPart 
= false;
            
this.scroll = this.maxscroll;
        }

        traceText.onKillFocus 
= function( newFocus )
        
{
            _logObj.allowChange 
= true;
            
if( _logObj.isPart ){
                
var myText = _logObj.traceText;
                
if!_logObj.lineCount ){
                    myText.text 
= '';
                    
return;
                }

                
var i = _logObj.length > lineCount ? _logObj.length - lineCount : 0;
                
var str:String = _logObj[i];
                
for++i; i<_logObj.length; i++ ){
                    str 
+= ' ' + _logObj[i];
                }

                myText.text 
= str;
                myText.scroll 
= myText.maxscroll;
            }

        }

        SetTraceFunc( _traceFunc );
    }


    static public 
function SetTraceVisible( isVisible )
    
{
        _traceVisible 
= isVisible == true;
        _logObj.traceText._visible 
= _traceVisible;
        
if!_logObj.lineCount || !_logObj.allowChange || !_traceVisible || _logObj.length == 0 ){
            
return;
        }

        
var myText = _logObj.traceText;
        
var lineCount = _logObj.lineCount;
        
var i = _logObj.length > lineCount ? _logObj.length - lineCount : 0;
        
var str:String = _logObj[i];
        
for++i; i<_logObj.length; i++ ){
            str 
+= ' ' + _logObj[i];
        }

        myText.text 
= str;
        myText.scroll 
= myText.maxscroll;
    }


    static public 
function SetTraceFunc( traceFunc )
    
{
        _traceFunc 
= traceFunc == undefined ? Trace : traceFunc;
    }


    static public 
function xtrace( msg:Object )
    
{
        
var indent = '';
        
forvar i=0; i<_indent; i++ ){
            indent 
+= '|   ';
        }

        _traceFunc( indent 
+ msg );
    }


    static private 
function Trace( msg:String )
    
{
        
if( _logObj == undefined ){
            
return;
        }

        
var myText = _logObj.traceText;
        
var lineCount = _logObj.lineCount;
        _logObj.push( msg );
        _logObj.isPart 
= true;
        
if!_logObj.lineCount || !_logObj.allowChange || !_traceVisible ){
            
return;
        }

        
var i = _logObj.length > lineCount ? _logObj.length - lineCount : 0;
        
var str:String = _logObj[i];
        
for++i; i<_logObj.length; i++ ){
            str 
+= ' ' + _logObj[i];
        }

        myText.text 
= str;
        myText.scroll 
= myText.maxscroll;
    }


    static private 
var _traceFunc = Trace;
    static private 
var _traceVisible = false;
    static private 
var _indent = 0;
    static private 
var _logObj;

    
//=========================================================
    //TraceClass====================================Version 1.1
    static public function TraceClass( name, obj, info )
    
{
        
if( _classTraceOn == false ){
            
return;
        }

        xtrace( 
'' + name + ' ] class created -----' + ( info == undefined ? '' : info ) );
        _global.ASSetPropFlags( obj.__proto__, 
null61 );
        
var control;
        
forvar i in obj ){
            
if( i != 'constructor' && typeof(obj[i]) == 'function' ){
                
if( control == undefined ){
                    control 
= new Object();
                    control.exclusiveCount 
= 0;
                }

                
if( obj[i] != undefined && obj[i].control == undefined ){
                    obj[i] 
= createRecallFunc( obj[i], name + '.' + i, control, info );
                }

            }

        }

    }


    static public 
function SwitchClassTrace( classTraceOn )
    
{
        _classTraceOn 
= classTraceOn == true;
    }


    
// 1 : only trace func
    // 2 : not trace func
    // 4 : not print trace info for func, but indent changes
    static public function SetFunctionTag( func, tag )
    
{
        
if( func.tag == undefined ){
            
return;
        }

        func.tag 
|= tag;
        
if( ( tag & 1 ) != 0 ){
            func.control.exclusiveCount
++;
        }

    }


    
//clear the tag setted, if tag is 0, clear all tags
    static public function ClearFunctionTag( func, tag )
    
{
        
if( func.tag == undefined ){
            
return;
        }

        tag 
= tag == 0 ? func.tag : tag;
        func.tag 
&= ~tag;
        
if( ( tag & 1 ) != 0 ){
            func.control.exclusiveCount
--;
        }

    }


    static private 
function createRecallFunc( orgFunc, funcName, control, info ):Function
    
{
        
var ret = new Function(
            
function()
            
{
                
return TraceCall( this, arguments );
            }

        );
        ret.orgFunc 
= orgFunc;
        ret.funcName 
= funcName;
        ret.control 
= control;
        ret.info 
= info;
        ret.tag 
= 0;
        
return ret;
    }


    static private 
function TraceCall( thisObj, arg )
    
{
        
var callee = arg.callee;
        
var callTrace = true;
        
if( callee.control.exclusiveCount > 0  ){
            callTrace 
= ( callee.tag & 1 ) != 0;
        }
else if( ( callee.tag & 2 ) != 0 ){
            callTrace 
= false;
        }

        
if( callTrace ){
            
if( ( callee.tag & 4 ) != 0 ){
                _indent
++;
            }
else{
                OnCallBegin( callee.funcName, callee.info );
            }

        }

        
var ret = callee.orgFunc.apply( thisObj, arg );
        
if( callTrace ){
            
if( ( callee.tag & 4 ) != 0 ){
                _indent
--;
            }
else{
                OnCallEnd( callee.funcName, callee.info, ret );
            }

        }

        
return ret;
    }


    static private 
function OnCallBegin( funcName, info )
    
{
        xtrace( 
'/---' + funcName + '-----' + ( info == undefined ? '' : info ) );
        _indent
++;
    }


    static private 
function OnCallEnd( funcName, info, ret )
    
{
        _indent
--;
        
var type = typeof( ret );
        
if( type == 'string' || type == 'number' || type == 'boolean' ){
            xtrace( 
'|---( ' + ret + ' )' );
        }

        xtrace( 
'/---' + funcName + '-----' + ( info == undefined ? '' : info ) );
    }


    static private 
var _classTraceOn = false;
}

 
### 如何在测试报告中记录、描述和展示Bug的最佳实践 在测试报告中记录、描述和展示Bug是一项系统性工作,需要结合模板化的方法和工具支持来确保信息的准确性和完整性。以下是一些最佳实践: #### 1. 使用结构化的Bug报告模板 为了保证Bug报告的完整性和一致性,建议使用结构化的模板。一个良好的模板通常包含以下几个关键部分[^1]: - **Bug标题**:简明扼要地描述问题的核心。 - **测试环境**:包括操作系统、浏览器版本、硬件配置等信息。 - **重现步骤**:详细列出导致Bug出现的具体操作步骤。 - **预期结果**:描述在正常情况下应该发生的行为。 - **实际结果**:描述Bug发生时的实际行为。 - **严重程度**:根据影响范围和修复优先级对Bug进行分类(如高、中、低)。 - **附加信息**:如截图、日志文件或视频,帮助开发人员更快定位问题。 #### 2. 利用高效的Bug记录工具 选择合适的Bug记录工具可以极大地提高工作效率。这些工具通常提供以下功能[^2]: - **任务跟踪**:将Bug与开发任务关联,便于团队协作。 - **状态管理**:通过“新建”、“已分配”、“修复中”、“已验证”等状态跟踪Bug处理进度。 - **支持和培训资源**:优秀的工具提供商通常会提供详尽的文档、活跃的社区和快速响应的客服支持。 #### 3. 统一日志记录机制 在软件开发过程中,统一的日志记录机制能够为Bug分析提供重要依据。例如,在SpringBoot项目中,可以通过配置日志框架(如Logback或SLF4J)实现统一的日志记录[^3]。以下是实现的关键点: - **日志级别**:合理设置日志级别(如DEBUG、INFO、WARN、ERROR),以便在不同场景下获取必要的信息。 - **日志格式**:定义统一的日志输出格式,确保日志内容清晰易读。 - **异常捕获**:在代码中加入全局异常处理器,自动记录错误日志。 #### 4. 数据可视化与报告生成 为了更直观地展示Bug信息,可以采用数据可视化工具生成测试报告。例如: - 使用图表展示Bug数量随时间的变化趋势。 - 分析Bug按模块分布的情况,帮助团队识别高风险区域。 - 提供交互式报告,允许用户筛选和查询特定条件下的Bug信息。 ```python import matplotlib.pyplot as plt # 示例:绘制Bug数量随时间变化的趋势图 dates = ['2023-01-01', '2023-01-08', '2023-01-15', '2023-01-22'] bug_counts = [10, 15, 8, 12] plt.plot(dates, bug_counts, marker='o') plt.title('Bug数量随时间变化趋势') plt.xlabel('日期') plt.ylabel('Bug数量') plt.grid(True) plt.show() ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值