首页 \ 问答 \ 扭曲线程如何避免深度拷贝(Twisted threading howto avoid deepcopy)

扭曲线程如何避免深度拷贝(Twisted threading howto avoid deepcopy)

我有一个扭曲的服务器,它为每个请求执行一些“长”任务,所以我推迟每个调用的线程。 在每个请求中,我访问一个公共资源,这个资源在这个过程中被修改。 每个请求应该从原始数据开始,所以我使用公共资源的深层拷贝(在调用锁获取时)。 它的工作原理,但我认为它不够快。 我有一种感觉,deepcopy会让事情变慢一点。

在具有资源突变的线程扭曲服务器中处理时,您有什么建议?


I have a twisted server which does some "long" task for each request so i defer to thread each call. In each request i access a common resource, which gets altered during the process. Each request should start with the original data so i use deepcopy on the common resource (while invoking a lock acquire). It works, BUT i think it's not fast enough. I have the feeling that deepcopy is slowing things a bit.

What suggestions do you have when dealing in a threaded twisted server with resources mutation ?


原文:https://stackoverflow.com/questions/7083427
更新时间:2023-07-29 20:07

最满意答案

这是一种使用对象扩展语法以可读方式有效完成此操作的方法。

let state = {
    authors : {
        ...this.state.authors, 
        [ givenId ] : { 
            ...this.state.authors[ givenID ], 
            bio : newValue 
        }
    }  
}
this.setState(state)

请记住,当您在jsx中映射项目时,必须传递一个“钥匙”作为道具。

这主要是因为,和解(React的“差异化”算法来检查发生了什么变化)的事情会对映射的jsx(大致命名为jsx)进行检查。

无论如何,管理状态state / setState或者redux与'和解'无关。

在这两种情况下,您都可以使用“Object Spread Syntax”语法更改嵌套数据的一部分。

所有你会关心剩下的就是将'相同'的键传递给映射的jsx。 因此,虽然反应放弃,但它不会尝试对不必要的部分进行dom更新,这很昂贵。


Thank you to jpdeatorre and daveols for pointing me at Redux.

Here is an example application (with tons of corner cutting, but it shows the technique) of using Redux to isolate components from state changes that are irrelevant to them.

In this example the changes to the author Alice with id 1 don't cause Author components that don't depend on Alice to have their render() called.

This is because Redux's supplied shouldComponentUpdate for its connected react components evaluates whether the props and if relevant state have changed.

Be forewarned that Redux's optimization here is shallow. To determine wither or not to skip render() Redux's shouldComponentUpdate checks if:

  • The old and new props are === to one another
  • Or, if not that they have the same keys and the values of those keys are === to one another.

So it could result in render() being called for components whose values are still logically equivalent however the props to those components and their first level keys do not compare as equal with ===. See: https://github.com/reactjs/react-redux/blob/master/src/utils/shallowEqual.js

Note also that in order to prevent calling render() on the "dumb" component of Author I had to connect() it to Redux to enable Redux's shouldComponentUpdate logic - even though that component is doing nothing at all with the state and just reads its props.

import ReactDOM from 'react-dom';
import React from 'react';

import { Provider, connect } from 'react-redux';
import { createStore, combineReducers } from 'redux';

import update from 'immutability-helper';


const updateAuthor = ( author ) => {
  return ( {
    type : 'UPDATE_AUTHOR',
    // Presently we always update alice and not a particular author, so this is ignored.
    author
  } );
};

const updateUnused = () => {
  return ( {
    type : 'UPDATE_UNUSUED',
    date : Date()
  } );
};

const initialState = {
  'authors': {
    1: {
      'name': 'Alice Author',
      'bio': 'Alice initial bio.'
    },
    2: {
      'name': 'Bob Baker',
      'bio': 'Bob initial bio.'
    }
  },
  'publications': {
    1 : {
      'title' : 'Two Authors',
      'authors' : [ 1, 2 ]
    },
    2 : {
      'title' : 'One Author',
      'authors' : [ 1 ]
    }
  }
};

const initialDate = Date();

const reduceUnused = ( state=initialDate, action ) => {
  switch ( action.type ) {
    case 'UPDATE_UNUSED':
      return action.date;

    default:
      return state;
  }
};

const reduceAuthors = ( state=initialState, action ) => {
  switch ( action.type ) {
    case 'UPDATE_AUTHOR':
      let new_bio = state.authors['1'].bio + ' updated ';
      let new_state = update( state, { 'authors' : { '1' : { 'bio' : {$set : new_bio } } } } );
      /*
      let new_state = {
        ...state,
        authors : {
          ...state.authors,
          [ 1 ] : {
            ...state.authors[1],
            bio : new_bio
          }
        }
      };
      */
      return new_state;

    default:
      return state;
  }
};

const testReducers = combineReducers( {
  reduceAuthors,
  reduceUnused
} );

const mapStateToPropsAL = ( state ) => {
  return ( {
    authors : state.reduceAuthors.authors
  } );
};

class AuthorList extends React.Component {

  render() {
    return (
      <div>
        { Object.keys( this.props.authors ).map( ( author_id ) => {
          return <Author key={author_id} author_id={author_id} />;
        } ) }
      </div>
    );
  }
}
AuthorList = connect( mapStateToPropsAL )(AuthorList);

const mapStateToPropsA = ( state, ownProps ) => {
  return ( {
    author : state.reduceAuthors.authors[ownProps.author_id]
  } );
};

class Author extends React.Component {

  render() {
    if ( this.props.author.name === 'Bob Baker' ) {
      alert( "Rendering Bob!" );
    }

    return (
      <div>
        <p>Name: {this.props.author.name}</p>
        <p>Bio: {this.props.author.bio}</p>
      </div>
    );
  }
}
Author = connect( mapStateToPropsA )( Author );


const mapStateToPropsPL = ( state ) => {
  return ( {
    authors : state.reduceAuthors.authors,
    publications : state.reduceAuthors.publications
  } );
};


class PublicationList extends React.Component {

  render() {
    console.log( 'Rendering PublicationList' );
    let authors = this.props.authors;
    let publications = this.props.publications;
    return (
      <div>
        { Object.keys( publications ).map( ( publication_id ) => {
          return <Publication key={publication_id} publication={publications[publication_id]} authors={authors} />;
        } ) }
      </div>
    );
  }
}
PublicationList = connect( mapStateToPropsPL )( PublicationList );


class Publication extends React.Component {

  render() {
    console.log( 'Rendering Publication' );
    let authors = this.props.authors;
    let publication_authors = this.props.publication.authors.reduce( function( obj, x ) {
      obj[x] = authors[x];
      return obj;
    }, {} );

    return (
      <div>
        <p>Title: {this.props.publication.title}</p>
        <div>Authors:
          <AuthorList authors={publication_authors} />
        </div>
      </div>
    );
  }
}

const mapDispatchToProps = ( dispatch ) => {
  return ( {
    changeAlice : ( author ) => {
      dispatch( updateAuthor( author ) );
    },
    changeUnused : () => {
      dispatch( updateUnused() );
    }
  } );
};

class TestApp extends React.Component {
  constructor(props) {
    super(props);
  }

  render() {
    return (
      <div>
        <p>
          <span onClick={ () => { this.props.changeAlice( this.props.authors['1'] ); } }><b>Click to Change Alice!</b></span>
        </p>
        <p>
          <span onClick={ () => { this.props.changeUnused(); } }><b>Click to Irrelevant State!</b></span>
        </p>

        <div>Authors:
          <AuthorList authors={this.props.authors} />
        </div>
        <div>Publications:
          <PublicationList authors={this.props.authors} publications={this.props.publications} />
        </div>
      </div>
    );
  }
}
TestApp = connect( mapStateToPropsAL, mapDispatchToProps )( TestApp );

let store = createStore( testReducers );

ReactDOM.render(
  <Provider store={store}>
    <TestApp />
  </Provider>,
  document.getElementById( 'test' )
);

相关问答

更多
  • 这是一种使用对象扩展语法以可读方式有效完成此操作的方法。 let state = { authors : { ...this.state.authors, [ givenId ] : { ...this.state.authors[ givenID ], bio : newValue } } } this.setState(state) 请记住,当您在jsx中映射项目时,必须传递一个 ...
  • 从外观handleChange ,您需要进行以下更改以handleChange更改: handleChange(e) { const { checked, value } = e.target; // Ensure that you're destructuring from fields let { friendsInEvent } = { ...this.state.fields }; if (checked) { friendsInEvent = [...friendsInE ...
  • 为此,React支持“ keyed children ”。 这基本上意味着将key={someUniqueId}属性添加到您的所有子组件。 “当React协调关键儿童时,它将确保任何有钥匙的孩子将被重新安排(而不是被破坏)或被销毁(而不是重复使用)。” 回答你的问题 这是一种效率极低的方法吗? 是的,如果您不使用键控子项来处理其中一个叶子中的每个小变化,整个树将从根目录重建。 For this React supports "keyed children". This basically means add ...
  • React没有定义你应该如何构建你的应用程序,也没有像其他一些框架(例如主干)那样建议“默认”架构。 另外,redux不是反应的必要组成部分。 它被用来防止状态分布在多个组件上 - 但本地状态不是反模式,你确实可以/应该有一些。 有关详细信息,请参阅redux合着作者的文章 。 关于你在图片上提供的架构,好吧,这看起来像传统的MVC。 “数据提供者组件”=模型 “智能组件”=控制器 “哑组件”=视图 再次,反应并没有定义什么是错的,什么是正确的。 你的想法看起来很好。 通过适当的实施,可以非常清楚地理解。 ...
  • 巴尼,你应该尝试将你的组件声明为一个类,这样你就可以用它进行状态管理。 查看这篇文档以获取有关如何使用状态的说明https://facebook.github.io/react-vr/docs/components-props-and-state.html 你的组件在状态中应该有一个选项列表和一个选择哪个选项的索引。 遍历列表并为选定的索引做特殊处理。 你可以让每个选项都是它自己的组件和用来标识它的索引,一个用于设置状态的onChange回调函数和一个isSelected prop。 如果选择了道具,您可以 ...
  • 通过像这样破坏状态来解决这个问题: handleInputChange = (e, key, taskKey) => { const value = e.target.value; const name = e.target.name; this.setState({ dataGoal: { ...this.state.dataGoal, [key]: { ...this.state.da ...
  • 没有推荐的方法; 你做的很棒。 There's no recommended way; what you've done looks great.
  • 您可以编写一个函数来返回对象中已完成待办事项的数量。 countCompleted: function(todos) { var todoKeys = Object.keys(todos); var completed = todoKeys.filter(function(key) { var todo = todos[key]; return todo.complete; }); return completed.length; } 然后从渲染中调用该函数以有条件地禁 ...
  • 这个无限循环是因为你在父组件的render函数中有一些东西,它调用setState或触发一些更新到另一个组件,这会影响原始或父组件的状态,然后再调用render。 在你的情况下,这是因为在TabItem.js中,
  • { item.text }
  • 实际上changeTabHandler立即调用changeTabHandler ,它将在Page中执行setState,然后Ta ...
  • 在React.Component使用ImmutableJS来管理状态是一个好主意(或方法)吗? 我不明白为什么这会是一个坏主意。 它甚至在React docs中提到过。 如果我可以为此目的使用ImmutableJS , this.state应该是一个不可变对象吗? 如果是这样,如何处理this.setState() ? 这真的取决于你。 使组件状态不可变是有好处的(比如能够使用PureComponent并获得优化的性能)。 我不确定你对“处理this.setState() ”的意思。 你继续像往常一样使用它 ...
  • 相关文章

    更多
  • Multicast over TCP/IP HOWTO
  • howto:solr安装
  • howto:使用solrj
  • POJ 3620 Avoid The Lakes【DFS水题练格式Avoid The Lakes Time Limit: 1000MS Memory Limit: 65536K Total Sub】
  • howto:solr全文检索配置
  • howto:solr post.jar使用
  • 关于线程的问题
  • 关于线程
  • SVG 绘制曲线polyline
  • Hibernate深度疑问
  • 最新问答

    更多
  • 您如何使用git diff文件,并将其应用于同一存储库的副本的本地分支?(How do you take a git diff file, and apply it to a local branch that is a copy of the same repository?)
  • 将长浮点值剪切为2个小数点并复制到字符数组(Cut Long Float Value to 2 decimal points and copy to Character Array)
  • OctoberCMS侧边栏不呈现(OctoberCMS Sidebar not rendering)
  • 页面加载后对象是否有资格进行垃圾回收?(Are objects eligible for garbage collection after the page loads?)
  • codeigniter中的语言不能按预期工作(language in codeigniter doesn' t work as expected)
  • 在计算机拍照在哪里进入
  • 使用cin.get()从c ++中的输入流中丢弃不需要的字符(Using cin.get() to discard unwanted characters from the input stream in c++)
  • No for循环将在for循环中运行。(No for loop will run inside for loop. Testing for primes)
  • 单页应用程序:页面重新加载(Single Page Application: page reload)
  • 在循环中选择具有相似模式的列名称(Selecting Column Name With Similar Pattern in a Loop)
  • System.StackOverflow错误(System.StackOverflow error)
  • KnockoutJS未在嵌套模板上应用beforeRemove和afterAdd(KnockoutJS not applying beforeRemove and afterAdd on nested templates)
  • 散列包括方法和/或嵌套属性(Hash include methods and/or nested attributes)
  • android - 如何避免使用Samsung RFS文件系统延迟/冻结?(android - how to avoid lag/freezes with Samsung RFS filesystem?)
  • TensorFlow:基于索引列表创建新张量(TensorFlow: Create a new tensor based on list of indices)
  • 企业安全培训的各项内容
  • 错误:RPC失败;(error: RPC failed; curl transfer closed with outstanding read data remaining)
  • C#类名中允许哪些字符?(What characters are allowed in C# class name?)
  • NumPy:将int64值存储在np.array中并使用dtype float64并将其转换回整数是否安全?(NumPy: Is it safe to store an int64 value in an np.array with dtype float64 and later convert it back to integer?)
  • 注销后如何隐藏导航portlet?(How to hide navigation portlet after logout?)
  • 将多个行和可变行移动到列(moving multiple and variable rows to columns)
  • 提交表单时忽略基础href,而不使用Javascript(ignore base href when submitting form, without using Javascript)
  • 对setOnInfoWindowClickListener的意图(Intent on setOnInfoWindowClickListener)
  • Angular $资源不会改变方法(Angular $resource doesn't change method)
  • 在Angular 5中不是一个函数(is not a function in Angular 5)
  • 如何配置Composite C1以将.m和桌面作为同一站点提供服务(How to configure Composite C1 to serve .m and desktop as the same site)
  • 不适用:悬停在悬停时:在元素之前[复制](Don't apply :hover when hovering on :before element [duplicate])
  • 常见的python rpc和cli接口(Common python rpc and cli interface)
  • Mysql DB单个字段匹配多个其他字段(Mysql DB single field matching to multiple other fields)
  • 产品页面上的Magento Up出售对齐问题(Magento Up sell alignment issue on the products page)