title: java performance questions about operator or
body: <p>It's a Snowflake algorithm. I implement by myself. Use generate to generate unique id.</p>
  
  <pre><code>// start time
  private final long startTimestamp = ZonedDateTime.of(2015, 1, 1, 0, 0, 0, 0, ZoneId.systemDefault()).toInstant().toEpochMilli();
  
  // shift value
  private final long workerDataLeftShiftValue;
  
  // mask
  private final long sequenceMask = 4095L;
  
  // sequence from  0 - 4095
  private long sequence = 0;
  
  // last timestamp
  private long lastTimestamp = System.currentTimeMillis();
  
  public Snowflake(int dataCenterId, int workerId) {
      // shifts
      int workerLeftShift = 12;
      int dataCenterLeftShift = 17;
      this.workerDataLeftShiftValue = workerId &lt;&lt; workerLeftShift | dataCenterId &lt;&lt; dataCenterLeftShift;
  
      // max id
      int maxId = 32;
      if (!(dataCenterId &lt; maxId) || !(workerId &lt; maxId)) {
          throw new IllegalStateException("not a valid id, snowflake is not working");
      }
  }
  
  @Override
  public synchronized long generate() {
      long curTimestamp = System.currentTimeMillis();
      if (lastTimestamp &gt; curTimestamp) {
          throw new IllegalStateException("last timestamp &gt; current timestamp, clock error when using snowflake");
      }
  
      if (lastTimestamp == curTimestamp) {
          sequence = (sequence + 1) &amp; sequenceMask;
          if (sequence == 0) {
              while (curTimestamp == System.currentTimeMillis()) {
                  curTimestamp = System.currentTimeMillis();
              }
          }
      } else {
          sequence = 0;
      }
  
      lastTimestamp = curTimestamp;
  
      return sequence | workerDataLeftShiftValue | (curTimestamp - startTimestamp) &lt;&lt; 22L;
  }
  
  public static void main(String[] args) {
      Snowflake snowflake = new Snowflake(1, 1);
      System.out.println(snowflake.generate());
  }
  </code></pre>
  
  <p>It's a Snowflake implemented by Twitter. Use nextId to generate unique id.</p>
  
  <pre><code>private final long twepoch = 1420041600000L;
  private final long workerIdBits = 5L;
  private final long datacenterIdBits = 5L;
  private final long maxWorkerId = -1L ^ (-1L &lt;&lt; workerIdBits);
  private final long maxDatacenterId = -1L ^ (-1L &lt;&lt; datacenterIdBits);
  private final long sequenceBits = 12L;
  private final long workerIdShift = sequenceBits;
  private final long datacenterIdShift = sequenceBits + workerIdBits;
  private final long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits;
  private final long sequenceMask = -1L ^ (-1L &lt;&lt; sequenceBits);
  
  private long workerId;
  private long datacenterId;
  private long sequence = 0L;
  private long lastTimestamp = -1L;
  
  public SnowflakeTwitter(long workerId, long datacenterId) {
      if (workerId &gt; maxWorkerId || workerId &lt; 0) {
          throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0", maxWorkerId));
      }
      if (datacenterId &gt; maxDatacenterId || datacenterId &lt; 0) {
          throw new IllegalArgumentException(String.format("datacenter Id can't be greater than %d or less than 0", maxDatacenterId));
      }
      this.workerId = workerId;
      this.datacenterId = datacenterId;
  }
  
  public synchronized long nextId() {
      long timestamp = timeGen();
  
      if (timestamp &lt; lastTimestamp) {
          throw new RuntimeException(
                  String.format("Clock moved backwards.  Refusing to generate id for %d milliseconds", lastTimestamp - timestamp));
      }
  
      if (lastTimestamp == timestamp) {
          sequence = (sequence + 1) &amp; sequenceMask;
          if (sequence == 0) {
              timestamp = tilNextMillis(lastTimestamp);
          }
      }
      else {
          sequence = 0L;
      }
  
      lastTimestamp = timestamp;
  
      return ((timestamp - twepoch) &lt;&lt; timestampLeftShift) //
              | (datacenterId &lt;&lt; datacenterIdShift) //
              | (workerId &lt;&lt; workerIdShift) //
              | sequence;
  }
  
  protected long tilNextMillis(long lastTimestamp) {
      long timestamp = timeGen();
      while (timestamp &lt;= lastTimestamp) {
          timestamp = timeGen();
      }
      return timestamp;
  }
  
  protected long timeGen() {
      return System.currentTimeMillis();
  }
  
  public static void main(String[] args) {
      SnowflakeTwitter idWorker = new SnowflakeTwitter(0, 0);
      System.out.println(idWorker.nextId());
  }
  </code></pre>
  
  <p>So I run some test performance on them. Use 10 threads to generate id. 1 Thread to watch the total number of id.</p>
  
  <pre><code>public static void main(String[] args) throws InterruptedException {
      Snowflake snowflake = new Snowflake(1, 1);
      SnowflakeTwitter snowflakeTwitter = new SnowflakeTwitter(1, 1);
      AtomicInteger sf = new AtomicInteger(0);
      AtomicInteger sft = new AtomicInteger(0);
  
      int tSize = 10;
      for (int i = 0; i &lt; tSize; i++) {
          new Thread(() -&gt; {
              while (true) {
                  snowflakeTwitter.nextId();
                  sft.incrementAndGet();
              }
          }).start();
          new Thread(() -&gt; {
              while (true) {
                  snowflake.generate();
                  sf.incrementAndGet();
              }
          }).start();
      }
      new Thread(() -&gt; {
          while (true) {
              System.out.println("sft: " + sft.get() + ", sf: " + sf.get());
              try {
                  TimeUnit.SECONDS.sleep(1);
              } catch (InterruptedException e) {
                  e.printStackTrace();
              }
          }
      }).start();
  
      TimeUnit.SECONDS.sleep(100);
  }
  </code></pre>
  
  <p>And result is:
  <code>
  sft: 6752, sf: 5663
  sft: 477792, sf: 194125
  sft: 1279909, sf: 661183
  sft: 2320410, sf: 1206993
  sft: 3374425, sf: 1712642
  sft: 4255803, sf: 2157003
  sft: 4661517, sf: 2338219
  sft: 5115752, sf: 2551146
  </code></p>
  
  <p>So my implmentation is slow. I found the reason is:
  <code>
          // my impl
          return sequence | workerDataLeftShiftValue | (curTimestamp - startTimestamp) &lt;&lt; 22L;
          // twitter impl
          return ((timestamp - twepoch) &lt;&lt; timestampLeftShift) //
                  | (datacenterId &lt;&lt; datacenterIdShift) //
                  | (workerId &lt;&lt; workerIdShift) //
                  | sequence;
  </code>
  Why caused the speed difference? Thanks.</p>