diff --git a/miner/src/cacluate.rs b/miner/src/cacluate.rs index 9e9a73d..825e9be 100644 --- a/miner/src/cacluate.rs +++ b/miner/src/cacluate.rs @@ -56,10 +56,12 @@ pub fn cacl(config: CacluateConfig, id: u64, outfile: &PathBuf) { // 提前准备好 team_namer let team_namer = TeamNamer::new(&config.team).unwrap(); + let mut main_namer = Namer::new_from_team_namer_unchecked(&team_namer, "dummy"); + for i in (config.start + id..config.end).step_by(config.thread_count as usize) { let name = gen_name(i); - let mut namer = Namer::new_from_team_namer_unchecked(&team_namer, name.as_str()); - let prop = namer.get_property(); + main_namer.replace_name(&team_namer, &name); + let prop = main_namer.get_property(); k += 1; if k >= report_interval { @@ -103,26 +105,26 @@ pub fn cacl(config: CacluateConfig, id: u64, outfile: &PathBuf) { let name = gen_name(i); let full_name = format!("{}@{}", name, config.team); // 虚评 - namer.update_skill(); + main_namer.update_skill(); - let xu = crate::evaluate::xuping::XuPing2_0_1015::evaluate(&namer); - let xu_qd = crate::evaluate::xuping::XuPing2_0_1015_QD::evaluate(&namer); + let xu = crate::evaluate::xuping::XuPing2_0_1015::evaluate(&main_namer); + let xu_qd = crate::evaluate::xuping::XuPing2_0_1015_QD::evaluate(&main_namer); if xu < config.qp_expect as f64 && xu_qd < config.qp_expect as f64 { continue; } get_count += 1; - info!("Id:{:>15}|{}|{:.4}|{:.4}|{}", i, full_name, xu, xu_qd, namer.get_info()); + info!("Id:{:>15}|{}|{:.4}|{:.4}|{}", i, full_name, xu, xu_qd, main_namer.get_info()); let write_in = format!( - // ,,,, + // ,,,, "{},{:>15},{:.4},{:.4},{}\n", full_name, i, xu, xu_qd, - namer.get_info_csv() + main_namer.get_info_csv() ); // 写入 (写到最后一行) diff --git a/miner/src/name.rs b/miner/src/name.rs index db867f5..fc4e649 100644 --- a/miner/src/name.rs +++ b/miner/src/name.rs @@ -293,6 +293,140 @@ impl Namer { } } + /// 更新当前的名字 + #[inline(always)] + pub fn replace_name(&mut self, team_namer: &TeamNamer, name: &str) { + self.val = team_namer.clone_vals(); + + let name_bytes = name.as_bytes(); + let name_len = name_bytes.len(); + let b_name_len = name_len + 1; + + for _ in 0..2 { + let mut s = 0_u8; + unsafe { + self.val.swap_unchecked(s as usize, 0); + let mut k = 0; + for i in 0..256 { + s = s.wrapping_add(if k == 0 { 0 } else { *name_bytes.get_unchecked(k - 1) }); + s = s.wrapping_add(*self.val.get_unchecked(i)); + self.val.swap_unchecked(i, s as usize); + k = if k == b_name_len - 1 { 0 } else { k + 1 }; + } + } + } + // simd! + #[cfg(feature = "simd")] + { + let mut simd_val = [0_u8; 256]; + let mut simd_val_b = [0_u8; 256]; + let simd_181 = u8x64::splat(181); + let simd_160 = u8x64::splat(160); + let simd_63 = u8x64::splat(63); + + for i in (0..256).step_by(64) { + unsafe { + let mut x = u8x64::from_slice(self.val.get_unchecked(i..i+64)); + x = x * simd_181 + simd_160; + x.copy_to_slice(simd_val.get_unchecked_mut(i..i+64)); + let y = x & simd_63; + y.copy_to_slice(simd_val_b.get_unchecked_mut(i..i+64)); + } + } + let mut mod_count = 0; + for i in 0..96 { + unsafe { + if simd_val.get_unchecked(i) > &88 && simd_val.get_unchecked(i) < &217 { + *self.name_base.get_unchecked_mut(mod_count as usize) = *simd_val_b.get_unchecked(i); + mod_count += 1; + } + } + if mod_count > 30 { + break; + } + } + if mod_count < 31 { + for i in 96..256 { + unsafe { + if simd_val.get_unchecked(i) > &88 && simd_val.get_unchecked(i) < &217 { + *self.name_base.get_unchecked_mut(mod_count as usize) = *simd_val_b.get_unchecked(i); + mod_count += 1; + } + } + if mod_count > 30 { + break; + } + } + } + } + #[cfg(not(feature = "simd"))] + { + let mut s = 0; + for i in 0..256 { + let m = ((self.val[i] as u32 * 181) + 160) % 256; + if m >= 89 && m < 217 { + self.name_base[s as usize] = (m & 63) as u8; + s += 1; + } + } + } + // 计算 name_prop + unsafe { + let mut prop_name = [0_u8; 32]; + prop_name.copy_from_slice(self.name_base.get_unchecked(0..32)); + prop_name.get_unchecked_mut(0..10).sort_unstable(); + *self.name_prop.get_unchecked_mut(0) = 154 + + *prop_name.get_unchecked(3) as u32 + + *prop_name.get_unchecked(4) as u32 + + *prop_name.get_unchecked(5) as u32 + + *prop_name.get_unchecked(6) as u32; + + *self.name_prop.get_unchecked_mut(1) = median( + *prop_name.get_unchecked(10), + *prop_name.get_unchecked(11), + *prop_name.get_unchecked(12), + ) as u32 + + 36; + *self.name_prop.get_unchecked_mut(2) = median( + *prop_name.get_unchecked(13), + *prop_name.get_unchecked(14), + *prop_name.get_unchecked(15), + ) as u32 + + 36; + *self.name_prop.get_unchecked_mut(3) = median( + *prop_name.get_unchecked(16), + *prop_name.get_unchecked(17), + *prop_name.get_unchecked(18), + ) as u32 + + 36; + *self.name_prop.get_unchecked_mut(4) = median( + *prop_name.get_unchecked(19), + *prop_name.get_unchecked(20), + *prop_name.get_unchecked(21), + ) as u32 + + 36; + *self.name_prop.get_unchecked_mut(5) = median( + *prop_name.get_unchecked(22), + *prop_name.get_unchecked(23), + *prop_name.get_unchecked(24), + ) as u32 + + 36; + *self.name_prop.get_unchecked_mut(6) = median( + *prop_name.get_unchecked(25), + *prop_name.get_unchecked(26), + *prop_name.get_unchecked(27), + ) as u32 + + 36; + *self.name_prop.get_unchecked_mut(7) = median( + *prop_name.get_unchecked(28), + *prop_name.get_unchecked(29), + *prop_name.get_unchecked(30), + ) as u32 + + 36; + } + + } + #[inline(always)] pub fn update_skill(&mut self) { let skill_id = self.skl_id.as_mut(); @@ -620,4 +754,26 @@ mod test { assert_eq!(name.name_prop.to_vec(), prop_vec); } + + #[test] + fn update_name_test() { + // 先创建一个正常的 namer + // 然后更新名字 + let team = TeamNamer::new_unchecked("x"); + let mut namer = Namer::new_from_team_namer_unchecked(&team, "x"); + + let update_name = "k"; + namer.replace_name(&team, update_name); + + let mut none_update_name = Namer::new_from_team_namer_unchecked(&team, update_name); + none_update_name.update_skill(); + namer.update_skill(); + + assert_eq!(namer.name_base.to_vec(), none_update_name.name_base.to_vec()); + assert_eq!(namer.name_prop.to_vec(), none_update_name.name_prop.to_vec()); + assert_eq!(namer.val.to_vec(), none_update_name.val.to_vec()); + assert_eq!(namer.skl_id.to_vec(), none_update_name.skl_id.to_vec()); + assert_eq!(namer.skl_freq.to_vec(), none_update_name.skl_freq.to_vec()); + + } } diff --git a/namerena-runner/src/rc4.rs b/namerena-runner/src/rc4.rs index b2a44f6..25c237b 100644 --- a/namerena-runner/src/rc4.rs +++ b/namerena-runner/src/rc4.rs @@ -260,16 +260,17 @@ impl RC4 { /// return X.map((e) => list[e]).toList(); /// } /// ``` - pub fn sort_list(&mut self, &mut list: Vec) { + pub fn sort_list(&mut self, list: &mut [T]) { if list.len() <= 1 { return; } let n = list.len(); // 直接对输入列表进行操作 + let mut b = 0; for _ in 0..2 { for a in 0..n { let key_v = self.next_i32(n as i32); - let b = (b + a + key_v) % n; + b = (b + a + key_v as usize) % n; list.swap(a, b); } } @@ -290,7 +291,7 @@ impl RC4 { /// return null; /// } /// ``` - pub fn pick(&mut self, list: Vec) -> Option { + pub fn pick(&mut self, list: &mut [T]) -> Option { match list.len() { 1 => Some(0), n if n > 1 => Some(self.next_i32(n as i32) as usize), @@ -327,7 +328,7 @@ impl RC4 { /// return null; /// } /// ``` - pub fn pick_skip(&mut self, list: Vec, skip_after_index: usize) -> Option { + pub fn pick_skip(&mut self, list: &mut [T], skip_after_index: usize) -> Option { match list.len() { 1 => { if skip_after_index == 0 { @@ -377,7 +378,7 @@ impl RC4 { /// return null; /// } /// ``` - pub fn pick_skip_range(&mut self, list: Vec, skips: Vec) -> Option { + pub fn pick_skip_range(&mut self, list: &mut [T], skips: Vec) -> Option { if skips.is_empty() { return self.pick(list); }